MySQL JDBC日期与不同时区的数据库服务器有关

时间:2012-06-22 13:05:12

标签: java mysql jdbc timezone

我在"欧洲/伦敦"有一个数据库服务器。时区和我的网络服务器在" Europe / Brussels"。由于现在是夏天,我的应用程序服务器有两个小时的差异。

我创建了一个测试来重现我的问题:

Query q = JPA.em().createNativeQuery("SELECT UNIX_TIMESTAMP(startDateTime) FROM  `Event`  WHERE  `id` =574");
BigInteger unix = (BigInteger) q.getSingleResult();
System.out.println(unix + "000 UNIX_TIMESTAMP to BigInteger");

Query q2 = JPA.em().createNativeQuery("SELECT startDateTime FROM  `Event`  WHERE  `id` =574");
Timestamp o = (Timestamp) q2.getSingleResult();
System.out.println(o.getTime() + " Timestamp");

startDateTime列定义为' datetime' (但是' timestamp'同样的问题) 我得到的输出是:

1340291591000 UNIX_TIMESTAMP to BigInteger
1340284391000 Timestamp

读取java日期对象会导致时区发生变化,我该如何解决这个问题?我希望jdbc驱动程序只设置" unix时间"它从Date对象中的服务器获取的值。

(适当的解决方案应该适用于任何时区组合,不仅适用于GMT中的db)

3 个答案:

答案 0 :(得分:1)

JDBC驱动程序正在使用运行它的JVM的时区设置。如果您在Europe / Brussels运行应用程序,它会假定时区。如果您的数据库服务器在另一个时区运行,则使用Java进行的计算结果可能与SQL中的计算结果不同。

答案 1 :(得分:1)

您可以设置MySQL Timestamp列类型和:

<bean id="dataSource" class="com.jolbox.bonecp.BoneCPDataSource" destroy-method="close">
    <property name="driverClass" value="com.mysql.jdbc.Driver"/>
    <property name="jdbcUrl" value="${jdbc.url}"/>
    <property name="username" value="${jdbc.user}"/>
    <property name="password" value="${jdbc.pass}"/>
    <property name="idleConnectionTestPeriodInMinutes" value="60"/>
    <property name="idleMaxAgeInMinutes" value="240"/>
    <property name="maxConnectionsPerPartition" value="30"/>
    <property name="minConnectionsPerPartition" value="10"/>
    <property name="partitionCount" value="3"/>
    <property name="acquireIncrement" value="5"/>
    <property name="statementsCacheSize" value="100"/>
    <property name="initSQL" value="SET time_zone='${database.timezone}'"/>

这是我的bonecp dataSource - &gt;看到initSQL这个查询是在每个mysql连接的init上执行的。如果您的Web服务器位于Europe / Brussels,请将此时区设置为$ {database.timezone},这对我有用。 如果你的mysql有空的时区表,你需要从Linux语言环境中导入它,如:

  

mysql_tzinfo_to_sql / usr / share / zoneinfo | mysql -u root -p mysql

答案 2 :(得分:0)

我能够使用连接字符串参数

解决此问题
useJDBCCompliantTimezoneShift=true&useSSPSCompatibleTimezoneShift=true

但我对此并不十分满意,因为当数据库不在UTC / GMT时区时会造成更多麻烦。