将 UTC 中的 ISO 8601 字符串转换为本地时间 - JodaTime 添加与本地时区相反的时间
Convert ISO 8601 string in UTC to local time - JodaTime is adding the opposite of local time zone
假设我有一个 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。它
看起来它实际上 添加 7 小时到 UTC 时间 - 这是为什么?
另外,它认为这两个时间都是MST时间。我以为
.withZoneUTC()
会解决这个问题。为什么会这样想?
这个方法是 "best" 做这个的方法吗(假设这些问题可以
固定)?
我一步步来:
dateParser.parseDateTime("2019-02-22T01:03:23Z")
给你 2 月 22 日的 01:03 UTC,如预期的那样(与 2 月 21 日在 18:03 偏移 -07:00 的同一时间点)。
dateTime.toLocalDateTime()
丢弃了 UTC 偏移信息,因此您在 01:03 获得了 2 月 22 日,没有时区信息。 A LocalDateTime
是没有时区信息的日期和时间,因此不对应任何时间点。
dateTime.toDate()
为您提供与 2 月 22 日相同的时间点 01:03 UTC,没有偏移量或时区信息。 Date
尽管它的名字在某种程度上与 LocalDateTime
相反:它是一个时间点,但不对应于一天中的任何特定时间。
"UTC: " + dateTime.toDate()
将 Date
附加到字符串。为此,隐式调用 Date.toString
以获得要附加到第一个字符串的字符串。 Date.toString
使用您当地的时区来呈现字符串(这种行为让很多人感到困惑)。所以你得到的时间点打印为Thu Feb 21 18:03:23 MST 2019
,这是正确的时间点,只是转换为山区标准时间。
localDateTime.toDate()
有问题。您是说要将日期和时间转换为时间点。 LocalDateTime
通过使用您当地的时区解决了这个问题,因此您得到的时间点等于 2 月 22 日的 01:03 MST(与 08:03 UTC 相同的时间点)。
"Local: " + localDateTime.toDate()
再次调用 toString
并使用 MST 呈现字符串。
It looks like it's actually adding 7 hours to the UTC time - why is that?
因为您丢弃了 UTC 日期和时间的信息,然后用 MST 解释它们。
Additionally, it thinks both times are in MST time. … Why is it thinking this?
不是。只是Date.toString
装糊涂
Is this method the "best" for doing this (assuming these problems can be fixed)?
如果您正在编写新代码,最好使用 java.time,现代 Java 日期和时间 API。如果您已经在使用 Joda-Time,可以开发一个很好的 Joda-Time 解决方案,并且您是否以及何时要迁移到 java.time.
是一个悬而未决的问题
我没有使用 Joda-Time 的经验,但这里有一个使用 java.time 的片段,以防您需要:
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[America/Denver]
无论如何,如果可以的话,尽量避免java.util.Date
。仅当您不可或缺地需要一个 Date
用于无法更改或不想立即更改的遗留 API 时,请在调用 API 之前进行转换。在这种情况下,请记住 Date
没有时区,因此在转换为 Date
.
之前无需转换为 MST
Date oldfashionedDateObject = Date.from(pointInTime);
System.out.println(oldfashionedDateObject);
Thu Feb 21 18:03:23 MST 2019
引用
Note that Joda-Time is considered to be a largely “finished” project.
No major enhancements are planned. If using Java SE 8, please migrate
to java.time
(JSR-310).
(来自 Joda-Time 主页)
链接
- Oracle tutorial: Date Time 解释如何使用 java.time.
- Joda-Time home page.
假设我有一个 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。它 看起来它实际上 添加 7 小时到 UTC 时间 - 这是为什么?
另外,它认为这两个时间都是MST时间。我以为
.withZoneUTC()
会解决这个问题。为什么会这样想?这个方法是 "best" 做这个的方法吗(假设这些问题可以 固定)?
我一步步来:
dateParser.parseDateTime("2019-02-22T01:03:23Z")
给你 2 月 22 日的 01:03 UTC,如预期的那样(与 2 月 21 日在 18:03 偏移 -07:00 的同一时间点)。dateTime.toLocalDateTime()
丢弃了 UTC 偏移信息,因此您在 01:03 获得了 2 月 22 日,没有时区信息。 ALocalDateTime
是没有时区信息的日期和时间,因此不对应任何时间点。dateTime.toDate()
为您提供与 2 月 22 日相同的时间点 01:03 UTC,没有偏移量或时区信息。Date
尽管它的名字在某种程度上与LocalDateTime
相反:它是一个时间点,但不对应于一天中的任何特定时间。"UTC: " + dateTime.toDate()
将Date
附加到字符串。为此,隐式调用Date.toString
以获得要附加到第一个字符串的字符串。Date.toString
使用您当地的时区来呈现字符串(这种行为让很多人感到困惑)。所以你得到的时间点打印为Thu Feb 21 18:03:23 MST 2019
,这是正确的时间点,只是转换为山区标准时间。localDateTime.toDate()
有问题。您是说要将日期和时间转换为时间点。LocalDateTime
通过使用您当地的时区解决了这个问题,因此您得到的时间点等于 2 月 22 日的 01:03 MST(与 08:03 UTC 相同的时间点)。"Local: " + localDateTime.toDate()
再次调用toString
并使用 MST 呈现字符串。
It looks like it's actually adding 7 hours to the UTC time - why is that?
因为您丢弃了 UTC 日期和时间的信息,然后用 MST 解释它们。
Additionally, it thinks both times are in MST time. … Why is it thinking this?
不是。只是Date.toString
装糊涂
Is this method the "best" for doing this (assuming these problems can be fixed)?
如果您正在编写新代码,最好使用 java.time,现代 Java 日期和时间 API。如果您已经在使用 Joda-Time,可以开发一个很好的 Joda-Time 解决方案,并且您是否以及何时要迁移到 java.time.
是一个悬而未决的问题我没有使用 Joda-Time 的经验,但这里有一个使用 java.time 的片段,以防您需要:
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[America/Denver]
无论如何,如果可以的话,尽量避免java.util.Date
。仅当您不可或缺地需要一个 Date
用于无法更改或不想立即更改的遗留 API 时,请在调用 API 之前进行转换。在这种情况下,请记住 Date
没有时区,因此在转换为 Date
.
Date oldfashionedDateObject = Date.from(pointInTime);
System.out.println(oldfashionedDateObject);
Thu Feb 21 18:03:23 MST 2019
引用
Note that Joda-Time is considered to be a largely “finished” project. No major enhancements are planned. If using Java SE 8, please migrate to
java.time
(JSR-310).
(来自 Joda-Time 主页)
链接
- Oracle tutorial: Date Time 解释如何使用 java.time.
- Joda-Time home page.