将UTC中的ISO 8601字符串转换为当地时间-Jodatime添加了本地时区的对立面



说我的 String等于 2019-02-23T07:58:21。这是从UTC中的系统时钟检索的时间。

我想将时间转换为系统当地时间的时间。

我正在使用JodaTime,因为它似乎可以轻松地做我想要的。


我尝试了什么:

DateTimeFormatter dateParser = ISODateTimeFormat.dateTimeNoMillis().withZoneUTC();
DateTime dateTime;
LocalDateTime localDateTime;
dateTime = dateParser.parseDateTime("2019-02-22T01:03:23Z");
localDateTime = dateTime.toLocalDateTime();
System.out.println("UTC: " + dateTime.toDate());
System.out.println("Local: " + localDateTime.toDate());

输出的内容:

UTC: Thu Feb 21 18:03:23 MST 2019
Local: Fri Feb 22 01:03:23 MST 2019

问题:

  • 设置为我系统的默认时区是MST,即UTC-7:00。它看起来实际上是在UTC时间添加 7个小时 - 为什么?

  • 此外,它都认为两次都在MST。我以为.withZoneUTC()可以解决这个问题。为什么这么认为?

  • 是这样做的"最佳"(假设这些问题可以修复)?

我逐步进行:

  1. dateParser.parseDateTime("2019-02-22T01:03:23Z")在UTC的2月22日为您提供了预期的2月22日(与2月21日的时间点相同的时间点 - 07:00)。
  2. dateTime.toLocalDateTime()将UTC偏移信息丢弃,因此您在01:03获得2月22日,没有时区信息。LocalDateTime是没有时区信息的日期和一天中的时间,因此与任何时间点不符。
  3. dateTime.toDate()为您提供与2月22日在01:03 UTC的时间点相同的时间点,而无需偏移或时区信息。尽管Date的名称是某种程度上的LocalDateTime:它是一个时间点,但与一天中的任何特定小时都不相对。
  4. "UTC: " + dateTime.toDate()Date附加到字符串。为此,隐式调用Date.toString以获取一个字符串以附加到第一个字符串。Date.toString使用您本地时区渲染字符串(此行为使许多人感到困惑)。因此,您获得的时间点被打印为Thu Feb 21 18:03:23 MST 2019,这是正确的时间点,仅转换为山区标准时间。
  5. localDateTime.toDate()是有问题的。您是说要将日期和时间转换为一个时间点。LocalDateTime通过使用您的本地时区解决此问题,因此您可以获得等于22的时间点,在01:03 MST(与08:03 UTC相同的点)。
  6. "Local: " + localDateTime.toDate()再次调用toString并使用MST渲染字符串。

看起来它实际上是在UTC时间添加 7个小时 - 为什么?

因为您正在丢弃日期和时间在UTC中的信息,然后在MST中解释它们。

此外,它都认为这两次都在MST。…为什么要这么想?

不是。只是Date.toString令人困惑。

此方法是这样做的"最佳"(假设可以解决这些问题)?

如果您正在编写新代码,最好使用Java。Time,现代Java日期和时间API。如果您已经在使用Joda Time,则可以开发与Joda Time的好解决方案,这是一个悬而未决的问题

我没有Joda Time的经验,但是这里是使用Java的片段。

    String systemUtcString = "2019-02-22T01:03:23Z";
    Instant pointInTime = Instant.parse(systemUtcString);
    ZonedDateTime denverDateTime = pointInTime.atZone(ZoneId.of("America/Denver"));
    System.out.println(denverDateTime);

2019-02-21T18:03:23-07:00 [美国/丹佛]

在任何情况下,如果可以的话,请避免使用java.util.Date。只有当您不可或缺地需要Date的遗留API时,您无法更改或不想更改现在,请在调用该API之前进行转换。在这种情况下,请记住Date没有时区,因此在转换为Date之前,无需转换为MST。

    Date oldfashionedDateObject = Date.from(pointInTime);
    System.out.println(oldfashionedDateObject);

thu 2月21日18:03:23 MST 2019

QUOTE

请注意,Joda Time被认为是一个"完成"项目。 没有计划进行重大增强。如果使用Java SE 8,请迁移 到java.time(JSR-310)。

(摘自Joda Time Homepeg)

链接

  • Oracle教程:解释如何使用Java.Time的日期时间。
  • Joda Time主页。

相关内容

  • 没有找到相关文章

最新更新