2013-03-04 94 views
3

我想将时间戳保存到数据库,而不会被jdbc驱动程序转换为本地时区。目前只有MySQL和PostgreSQL对我很重要,但如果有独立于数据库的解决方案,我将不胜感激。JDBC/MySQL:始终使用UTC保存时间戳

实施例:

// i want that to be saved as 1970-01-01 00:00:00 
TimeStamp ts = new java.sql.Timestamp(0); 

// gets transformed to local time by jdbc driver (in my case to 1970-01-01 01:00:00) 
st.setTimestamp(0, new java.sql.Timestamp(0)); 

// only works using postgres (mysql connector seems to ignore the calendar) 
// postgres => 1970-01-01 00:00:00 
// mysql => 1970-01-01 01:00:0 
Calendar calutc = Calendar.getInstance(TimeZone.getTimeZone("UTC")); 
st.setTimestamp(0, new java.sql.Timestamp(0), utccal); 

我已经尝试来计算得到转化为正确的值的时间戳值(例如-3600000 => 1970-01-01 00:00:00在我的时区)但这对于日间节省时间变化附近的日期postgres无效。

回答

11

我找到了解决方案。 MySQL在其JDBC连接器中有一个错误,忽略了提供的Calendar对象setTimestamp/getTimestamp。他们修复了连接器版本5.1.5中的错误,但旧的(不正确的)行为仍然是默认行为。要使用正确的代码,您必须将参数“useLegacyDatetimeCode = false”传递给连接器url。

进一步的信息: http://bugs.mysql.com/bug.php?id=15604

+1

我使用'&serverTimezone = UTC&useLegacyDatetimeCode = false'成功,没有serverTimezone jdbc驱动程序抱怨错误的时区。 – snowindy 2014-11-04 16:51:26

+1

完整的URL,供参考:jdbc:mysql:// localhost:3306/pm_func?characterEncoding = UTF-8&useEncoding = true&autoReconnect = true&serverTimezone = UTC&useLegacyDatetimeCode = false – snowindy 2014-11-04 16:51:45

0

Java中的日期和时间戳是与时区无关的。新的时间戳(0)确实对应于UTC中的1970-01-01 00:00:00。您必须使用SimpleDateFormat并在其上设置所需的时区,以便可视化检查日期。使用System.out.println打印时,从时间戳中减去一个长常量使其看起来“正确”是非常错误的。

使用数据库时,您可以选择日期/时间/时间戳的数据类型。其中一些支持时区信息,有些则不支持。如果您选择在数据库中使用时区处理,则必须详细了解它。如果您想绕过它,您可以选择将日期/时间/时间戳作为字符串存储在数据库中,并在Java代码中进行所有格式化。

+0

据我知道JDBC仅支持的setTimestamp为日期和时间值(的setDate仅日期),其确实的时区转化。我认为正确的解决方案是具有Calendar属性的setTimestamp。我发现MySQL连接器属性“useLegacyDatetimeCode = false”似乎符合MySQL的jdbc兼容行为(@MySQL:wtf?) – Werzi2001 2013-03-05 08:05:51

+0

PostgreSQL有几种日期/时间类型:带时区的时间戳,不带时区的时间戳,日期,时间时区,没有时区的时间。我敢打赌MySQL有类似的多种类型。不幸的是,我认为这些类型不是标准化的,所以不同的数据库有类似但不相同的日期/时间类型。 – Olaf 2013-03-05 14:41:38

+0

是的,这是真的。但问题是告诉jdbc驱动程序应该使用哪个时区来保存时间戳。默认是使用本地时区,但我想使用utc。因此,存在MySQL时默认会忽略的getTimestamp/setTimestamp的Calendar参数。详情请参阅我自己的答案。 – Werzi2001 2013-03-05 15:24:05