mysql服务器和客户端时区不同,使用jdbc得到的结果差8小时的问题

默认情况下mysqltime_zoneSYSTEM,也就是mysql的时区和服务器的时区是一样的。一般服务器都是东八区。在使用mysql时,客户端所在的时区一般也是东八。所以从mysql查询timestamp类型数据时一切正常。

现在如果我们的条件是这样的:

1. 使用的jdbc url长这样jdbc:mysql://localhost:3306/table_name
2. 客户端的时区为零时区
3. mysql的时区是东八区

上面几个条件如果满足了,这时候你从mysql查找timestamp的数据,拿到的timestamp值和数据库中的值是一样的,没有考虑时区的问题,所以事实上是多了8小时。

String canonicalTimezone = getServerTimezone();
   if ((getUseTimezone() || !getUseLegacyDatetimeCode()) && configuredTimeZoneOnServer != null) {
       // user can override this with driver properties, so don't detect if that's the case
       if (canonicalTimezone == null || StringUtils.isEmptyOrWhitespaceOnly(canonicalTimezone)) {
           try {
               canonicalTimezone = TimeUtil.getCanonicalTimezone(configuredTimeZoneOnServer
               										, getExceptionInterceptor());
            } catch (IllegalArgumentException iae) {
               throw SQLError.createSQLException(iae.getMessage(), 
               		SQLError.SQL_STATE_GENERAL_ERROR, getExceptionInterceptor());
           }
       }
   }
   if (canonicalTimezone != null && canonicalTimezone.length() > 0) {
       this.serverTimezoneTZ = TimeZone.getTimeZone(canonicalTimezone);

getServerTimezone()方法拿到的值默认为nullgetUseTimezone()getUseLegacyDatetimeCode()方法得到的值分别是falsetrue,这样就导致了connector不会使用数据库的time zone。所以我们从数据库内读取timestamp数据,不做任何时区转化。

如果想要开启时区转换,需要将useTimezone设置为true, 即jdbc:mysql://localhost:3306/table_name?useTimezone=true

useTimezone
Convert time/date types between client and server time zones (true/false, defaults to ‘false’)? This is part of the legacy date-time code, thus the property has an effect only when “useLegacyDatetimeCode=true.”
Default: false

useTimezone设置为true后,还有一点很重要,如果mysqltime_zoneSYSTEM,连接数据库是会报错的,需要给定一个明确的时区。我们可以把数据库的time_zone设置为==+08:00==,这样timestamp的数据就会根据时区进行转换。 如果不想修改数据库的time_zone,可以在客户端进行设置,指定time_zone:

jdbc:mysql://localhost:3306/table_name?useTimezone=true&serverTimezone=GMT%2B8
#GMT%2B8表示东八区。

你可能感兴趣的:(JDBC,数据库,MySQL)