【问题标题】:How to convert Joda DateTime to UTC MySql timestamp如何将 Joda DateTime 转换为 UTC MySql 时间戳
【发布时间】:2013-10-07 09:09:55
【问题描述】:

我有一个代表 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 的 Timestamp 说:“MySQL 将 TIMESTAMP 值从当前时区转换为 UTC 进行存储,然后从 UTC 转换回当前时区进行检索。”, 所以我认为这是导致问题的 MySql 转换,因为它正在初始化的毫秒是相对于固定的 UTC 时间,所以它不需要从当前时区转换为 UTC。

我将数据读回 DateTime 的代码工作正常,并且我得到了我输入的值,但我还需要它来处理一些第 3 方代码 我无法控制,它希望时间戳处于正确的 UTC 时间。

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

【问题讨论】:

    标签: java mysql datetime timestamp utc


    【解决方案1】:

    tl;博士

    使用取代 Joda-Timejava.time 类。

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

    检索。

    myResultSet.getObject( 
        … ,
        Instant.class 
    )
    

    java.time

    Joda-Time 项目现在处于维护模式,建议迁移到其继任者,Java 8 及更高版本中内置的 java.time 类。两者都由同一个人斯蒂芬科尔伯恩领导。您会发现许多相同的概念都在发挥作用,因此非常容易迁移。

    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-Time 项目现在位于maintenance mode,建议迁移到java.time 类。

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

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

    从哪里获得 java.time 类?

    ThreeTen-Extra 项目通过附加类扩展了 java.time。该项目是未来可能添加到 java.time 的试验场。您可以在这里找到一些有用的类,例如IntervalYearWeekYearQuartermore

    【讨论】:

      猜你喜欢
      • 2016-06-19
      • 2013-04-06
      • 2011-12-18
      • 2013-09-12
      • 2013-10-22
      • 1970-01-01
      • 1970-01-01
      • 2011-05-01
      • 2011-06-07
      相关资源
      最近更新 更多