将SQL UTC时间戳转换为本地时区Java

时间:2017-11-05 04:09:42

标签: java sql datetime

我有以下代码。我已经在mySQL数据库中存储了一段时间,并希望在将其从数据库中提取时将其转换为本地时间。

        Instant startInstant = rs.getTimestamp(5).toInstant();
        Instant endInstant = rs.getTimestamp(6).toInstant();
        ZoneId z = ZoneId.of(TimeZone.getDefault().getID());

        ZonedDateTime start = startInstant.atZone(z);
        ZonedDateTime end = startInstant.atZone(z);


        System.out.println(start.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss VV")));
        System.out.println(end.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss VV")));

这是我得到的输出:

2017-11-01 01:40:00 America/Chicago
2017-11-01 01:40:00 America/Chicago

日期和时间与我的数据库中的相同:这是表格中的字段值:

2017-11-01 01:40:00

似乎唯一更新的只是美国/芝加哥的zoneID,这对我所需要的功能毫无用处。

关于我出错的地方的任何指示?

2 个答案:

答案 0 :(得分:0)

您尚未提供足够的信息来提供确切的答案。您没有在日期时间值周围解释完全列的数据类型。我怀疑你没有使用MySQL等同于TIMESTAMP WITH TIME ZONE的SQL标准类型。

我也想知道为什么你的存储值示例缺少任何来自UTC或时区的偏移量。这很可疑。

最后,您可能会使用具有默认时区的交互式SQL会话查看存储的值,并在会话中显示之前动态应用于从数据库检索的值。善意的,我认为这是一个反特征,因为它掩盖了存储数据的真实性质。这种行为可以解释你的困惑。尝试将会话的默认时区明确设置为UTC。

您的代码存在其他问题......

完全省略java.sql.Timestamp的使用。如果JDBC驱动程序支持JDBC 4.2或更高版本,则可以直接使用java.time类型。

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

不要将像TimeZone这样的旧遗留类与现代java.time类混合使用。遗留类完全被java.time取代;很好的解脱。

ZoneId z = ZoneId.systemDefault() ;

答案 1 :(得分:0)

您获得的数据与您在数据库中输入的值相同。 您在数据库中有时间戳值,但是如何表示存储的值  是UTC(值可能是UTC但不是UTC格式,所以通过查看值,你不能说这个值是UTC - >'2017-11-01 01:40:00')

如果你想获取不同时区的值,你也可以这样做:

例如: SET time_zone ='+ 03:00'; SELECT值 FROM table;

它将为您提供指定时区的价值。