如何将Joda DateTime转换为UTC MySql时间戳

时间:2013-10-07 09:09:55

标签: java mysql datetime timestamp utc

我有一个表示UTC时间的Joda DateTime对象,并希望将其存储在MySql表的Timestamp字段中。

我有以下代码:

String ztime = "2013-10-07T08:00:00Z";  

DateTimeFormatter parser = ISODateTimeFormat.dateTimeParser();
DateTime dt = parser.parseDateTime(ztime).withZone(DateTimeZone.UTC);

PreparedStatement stmt = con.prepareStatement("insert into time_test (time) values (?)");
stmt.setTimestamp(1, Timestamp(dt.getMillis()));
stmt.execute();

然而,当我查看数据库时,获取存储的时间超出了我的数据库与UTC时区的差异。 例如当我的数据库以UTC + 1运行,并运行上面的代码来保存" 08:00Z"时,数据库中的时间戳显示为09:00。

DateTime的getMillis方法说"获取1970-01-01T00:00:00Z的Java纪元的日期时刻的毫秒数。" 和MySql的时间戳说:" MySQL将TIMESTAMP值从当前时区转换为UTC进行存储,然后从UTC返回到当前时区进行检索。", 所以我认为导致问题的是MySql转换,因为它初始化的毫秒是相对于固定的UTC时间,所以它不需要从当前时区转换到UTC。

我将数据读回到DateTime的代码工作正常,我得到了我输入的值,但是我还需要这个来处理一些第三方代码 我没有控制权,它希望Timestamp处于正确的UTC时间。

如何让数据库中的Timestamp字段与我原来的UTC日期/时间相匹配?

1 个答案:

答案 0 :(得分:0)

tl; dr

使用代替 Joda-Time java.time 类。

myPreparedStatement.setObject( 
    … , 
    Instant.parse( "2013-10-07T08:00:00Z" )  
)

检索。

myResultSet.getObject( 
    … ,
    Instant.class 
)

java.time

Joda-Time 项目现在处于维护模式,建议迁移到其后继程序,即Java 8及更高版本中内置的 java.time 类。两者均由同一个人Stephen Colebourne领导。您会在游戏中发现许多相同的概念,因此相当容易迁移。

Instant类表示UTC中时间轴上的时刻,分辨率为nanoseconds(十进制小数的九(9)位)。

您输入的字符串恰好是标准ISO 8601格式。 java.time 类在解析/生成字符串时默认使用这些标准格式。因此,无需指定格式设置模式。

String input = "2013-10-07T08:00:00Z" ;     // Standard ISO 8601 format.
Instant instant = Instant.parse( input ) ;  // Parses standard ISO 8601 format by default.

Instant类将同时替换java.util.Datejava.sql.Timestamp。从JDBC 4.2及更高版本开始,您可以直接与数据库交换java.time对象。

myPreparedStatement.setObject( … , instant ) ;

和检索。

Instant instant = myResultSet.getObject( … , Instant.class ) ;

MySQL中的TIMESTAMP类型似乎类似于SQL标准的TIMESTAMP WITH TIME ZONE类型。因此,上面的代码应该可以正常工作。


关于 java.time

java.time框架已内置在Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.DateCalendarSimpleDateFormat

目前位于Joda-Timemaintenance mode项目建议迁移到java.time类。

要了解更多信息,请参见Oracle Tutorial。并在Stack Overflow中搜索许多示例和说明。规格为JSR 310

您可以直接与数据库交换 java.time 对象。使用符合JDBC driver或更高版本的JDBC 4.2。不需要字符串,不需要java.sql.*类。

在哪里获取java.time类?

ThreeTen-Extra项目使用其他类扩展了java.time。该项目为将来可能在java.time中添加内容提供了一个试验场。您可能会在这里找到一些有用的类,例如IntervalYearWeekYearQuartermore