【问题标题】:How do you save a UTC Timestamp?如何保存 UTC 时间戳?
【发布时间】:2017-10-05 17:23:44
【问题描述】:

如何将 ZonedDateTime 转换为 SQL Timestamp 并保留时区信息? 我正在尝试采用 UTC 分区时间,将其转换为 Timestamp,然后将其转换回来,但是当我转换为 Timestamp 时,它会丢失时区信息并且 Timestamp 是使用我的本地时间创建的区域:

public static void main(String[] args) {

    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("hh:mm a");

    ZonedDateTime zdtUTC = ZonedDateTime.now(ZoneId.of("UTC"));

    ZonedDateTime zdtNY = zdtUTC.withZoneSameInstant(ZoneId.of("America/New_York"));
    ZonedDateTime zdtAZ = zdtUTC.withZoneSameInstant(ZoneId.of("America/Phoenix"));
    ZonedDateTime zdtUK = zdtUTC.withZoneSameInstant(ZoneId.of("Europe/London"));

    System.out.println(formatter.format(zdtUTC) + " in UTC zone");
    System.out.println(formatter.format(zdtNY) + " in New York, NY");
    System.out.println(formatter.format(zdtAZ) + " in Phoenix, AZ");
    System.out.println(formatter.format(zdtUK) + " in London, UK");

    Timestamp timestamp = Timestamp.from(zdtUTC.toInstant());

    LocalDateTime converted = timestamp.toLocalDateTime();
    ZonedDateTime convertedZdt = ZonedDateTime.of(converted, ZoneId.of("UTC"));

    System.out.println(timestamp);

    System.out.println(formatter.format(convertedZdt) + " in UTC zone");

}

06:33 PM in UTC zone
02:33 PM in New York, NY
11:33 AM in Phoenix, AZ
07:33 PM in London, UK
2017-05-07 14:33:06.745
02:33 PM in UTC zone

我需要做些什么来确保Timestamp 记录使用正确的时区信息?

【问题讨论】:

  • 您可以成功使用'& server Timezone=UTC&use Legacy Date time Code=false'
  • SQL 时间戳没有时区——它只是一个瞬间。如果您需要单独的时区,我建议将时区 ID 存储在单独的列中。如果您只关心那个时间点的偏移量,您可以存储它 - 但您需要注意这与存储时区相同。
  • 我知道这与存储时区不同,但我需要能够存储 UTC 时区中那个时刻的绝对时间。我不允许更改数据库表。所以如果我在纽约并且现在是纽约时间下午 3 点,它需要存储为上午 11 点,同样,如果我在伦敦并且它是下午 4 点,它需要存储为下午 3 点。否则从数据库中检索Timestamp 时我没有参考点。
  • 对,所以您不需要存储偏移量或时区 - 您只需要通过声音及时存储瞬间。目前尚不清楚您为什么在示例代码中将任何内容转换为 LocalDateTime...

标签: java jdbc timestamp zoneddatetime


【解决方案1】:

当我转换为时间戳时,它会丢失时区信息,并且时间戳是使用我的本地时区创建的

没有。当您将原始的 ZonedDateTime zdtUTC 转换为 java.sql.Timestamp 时,您将获得相同的时间。这可以通过直接格式化和显示timestamp 值来验证:

Timestamp timestamp = Timestamp.from(zdtUTC.toInstant());  // as before
// verify the timestamp value directly
java.text.SimpleDateFormat sdfUTC = new java.text.SimpleDateFormat("hh:mm a z");
sdfUTC.setCalendar(java.util.Calendar.getInstance(java.util.TimeZone.getTimeZone("UTC")));
System.out.printf("timestamp is %s%n", sdfUTC.format(timestamp));

这将打印与输出的第一行相同的值:

08:30 PM in UTC zone
...
timestamp is 08:30 PM UTC

这是“丢失”时区信息的后续转换为LocalDateTime,然后返回ZonedDateTime

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-02-18
    • 2020-01-14
    • 1970-01-01
    • 2014-11-21
    • 1970-01-01
    • 2012-07-24
    • 1970-01-01
    • 2016-02-16
    相关资源
    最近更新 更多