来自ZonedDateTime的日期不在utc中

时间:2017-11-21 10:22:30

标签: java date timezone

我正在创建这样的日期:

ZonedDateTime now = ZonedDateTime.now(ZoneOffset.UTC);
Date.from(now.toInstant());

我需要Date对象在utc中有当前时间,但是当我打印日期时它给了我当地时间而不是时间。 我也尝试过:

 OffsetDateTime now = OffsetDateTime.now(ZoneOffset.UTC);
 Date date = Date.from(now.toInstant());

但是当我再次打印Date时,时间不在utc中。我在创建Date对象时做错了什么。为什么以上两种方法没有给我一个当前时间在utc的日期。

1 个答案:

答案 0 :(得分:2)

两点:

  1. 避免使用过时的Date类,特别是当您已经使用现代Java日期和时间API java.time中的类时。
  2. Date对象没有,也没有时区。
  3. 打印偏移或时区

    如果您需要抵消,则需要保留OffsetDateTime(或ZonedDateTime)对象:

        OffsetDateTime now = OffsetDateTime.now(ZoneOffset.UTC);
        System.out.println(now);
    

    在我刚才打印的电脑上

    2017-11-21T11:53:11.519Z
    

    最后的Z表示Zulu时区,UTC的另一个名称(您也可以非正式地将其视为 Z 与UTC的距离)。

    如果您想要一种更易读的格式,那么您是对的,请使用格式化程序:

        DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.FULL);
        ZonedDateTime now = ZonedDateTime.now(ZoneOffset.UTC);
        System.out.println(now.format(formatter));
    

    根据您的区域设置和时间,这会打印类似

    的内容
    Tuesday, November 21, 2017 11:53:11 AM Z
    

    Z再次表示祖鲁时区,UTC。

    Date不会帮助你

    Date只是一个时间点。您用于初始化日期的Instant也是如此。他们都没有时区或偏移。这里的区别在于他们的toString方法:Instant始终以UTC格式打印,Date通常(始终是?)在JVM的默认时区中。后者让许多人感到困惑,认为Date有一个时区没有时区。请参阅All about java.util.Date

    正如我所演示的,格式化器可以在格式化日期时间时将时区或偏移量放入字符串。这不会以任何方式修改日期时间对象,无论是OffsetDateTimeZonedDateTimeInstant还是Date。格式化DateFormat时,过时的Date类可能会执行相同操作。它不能也不会在Date对象中设置时区,因为(并且我重复)Date对象不能包含时区。

    长话短说,你不需要我能看到的过时的Date课程。