【问题标题】:Format a local date at another time zone在另一个时区格式化本地日期
【发布时间】:2017-11-06 10:09:27
【问题描述】:

我尝试在 2 个地点格式化当前时间:芝加哥和东京

LocalDateTime now = LocalDateTime.now();
ZonedDateTime chicago = now.atZone(ZoneId.of("America/New_York"));
System.out.println("chicago: " + chicago);
System.out.println("Chicago formated: " + chicago.format(DateTimeFormatter.ofLocalizedTime(FormatStyle.FULL)));

ZonedDateTime tokyo = now.atZone(ZoneId.of("Asia/Tokyo"));
System.out.println("Tokyo: " + tokyo);
System.out.println("Tokyo formated: " + tokyo.format(DateTimeFormatter.ofLocalizedTime(FormatStyle.FULL)));

打印出来:

chicago: 2017-11-05T18:19:01.441-05:00[America/New_York]
Chicago formated: 6:19:01 PM EST
Tokyo: 2017-11-05T18:19:01.441+09:00[Asia/Tokyo]
Tokyo formated: 6:19:01 PM JST

下午 6:19:01 为芝加哥和东京印刷。为什么?

感谢 Andreas 使上述代码正常工作。 按照您的逻辑,我尝试使这项工作:

LocalDateTime PCTime = LocalDateTime.now();//Chicago: 7:51:54 PM
ZonedDateTime newYorkTime = PCTime.atZone(ZoneId.of("America/New_York"));
System.out.println("now: " + newYorkTime);
System.out.println("now fmt: " + newYorkTime.format(DateTimeFormatter.ofLocalizedTime(FormatStyle.FULL)));
ZonedDateTime newYorkTime0 = newYorkTime.withZoneSameInstant(ZoneId.of("America/New_York"));
System.out.println("N.Y. fmt: " + newYorkTime0.format(DateTimeFormatter.ofLocalizedTime(FormatStyle.FULL)));

输出:

now: 2017-11-05T19:51:54.940-05:00[America/New_York]
now fmt: 7:51:54 PM EST
N.Y. fmt: 7:51:54 PM EST

最后一行应该是N.Y. fmt: 8:51:54 PM EST

【问题讨论】:

  • 了解LocalDateTime 不是特定的时间点。这只是全球至少 26 小时内可能出现的时刻的粗略概念。在您提供特定时区的上下文之前,它没有任何意义。除非您说“芝加哥下午 6 点”或“东京下午 6 点”,否则说“下午 6 点”是没有意义的。
  • 作为already stated in my answer,调用LocalDateTime.atZone() 只是分配一个时区,它不会改变时间。 PCTime任何 时区的下午 7:51,因此 newYorkTime 是美国东部标准时间晚上 7:51。如果你想改变时间,你首先要指定PCTime的时区,例如PCTime.atZone(ZoneId.systemDefault())由于系统默认时区用于获取本地时间,然后使用withZoneSameInstant(ZoneId.of("America/New_York"))转换为新时区,如我的回答所示。
  • 很好的解释!

标签: java date format


【解决方案1】:

LocalDateTime.atZone() 表示:取这个当地时间,并认为它是这个时区的当地时间。

这意味着芝加哥的“当地时间”下午 6:19 是美国东部时间时区的下午 6:19,而东京的“当地时间”下午 6:19 是美国东部时间下午 6:19时区 JST。

当您调用LocalDateTime.now() 时,您会获得当前默认时区的当地时间,但返回的值不知道是哪个时区。正如javadoc 所说:

此类不存储或表示时区。相反,它是对日期的描述,用于生日,结合挂钟上的当地时间。如果没有偏移或时区等附加信息,它不能代表时间线上的瞬间。

如果您想查看当前的实时时间并查看芝加哥和东京的时间,那么您需要使用通用时间 (Instant) 或知道什么时间的时间它代表的区域 (ZonedDateTime)。

使用Instant

Instant now = Instant.now();
ZonedDateTime chicago = now.atZone(ZoneId.of("America/New_York"));
System.out.println("Chicago: " + chicago);
System.out.println("Chicago formated: " + chicago.format(DateTimeFormatter.ofLocalizedTime(FormatStyle.FULL)));

ZonedDateTime tokyo = now.atZone(ZoneId.of("Asia/Tokyo"));
System.out.println("Tokyo: " + tokyo);
System.out.println("Tokyo formated: " + tokyo.format(DateTimeFormatter.ofLocalizedTime(FormatStyle.FULL)));

输出

Chicago: 2017-11-05T20:02:45.444-05:00[America/New_York]
Chicago formated: 8:02:45 PM EST
Tokyo: 2017-11-06T10:02:45.444+09:00[Asia/Tokyo]
Tokyo formated: 10:02:45 AM JST

使用ZonedDateTime

ZonedDateTime now = ZonedDateTime.now();
ZonedDateTime chicago = now.withZoneSameInstant(ZoneId.of("America/New_York"));
System.out.println("Chicago: " + chicago);
System.out.println("Chicago formated: " + chicago.format(DateTimeFormatter.ofLocalizedTime(FormatStyle.FULL)));

ZonedDateTime tokyo = now.withZoneSameInstant(ZoneId.of("Asia/Tokyo"));
System.out.println("Tokyo: " + tokyo);
System.out.println("Tokyo formated: " + tokyo.format(DateTimeFormatter.ofLocalizedTime(FormatStyle.FULL)));

输出

Chicago: 2017-11-05T20:04:19.368-05:00[America/New_York]
Chicago formated: 8:04:19 PM EST
Tokyo: 2017-11-06T10:04:19.368+09:00[Asia/Tokyo]
Tokyo formated: 10:04:19 AM JST

【讨论】:

  • 谢谢安德烈亚斯。我按照您的逻辑编写了另一段代码。但它不起作用。请参阅上面原始问题中添加的代码。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-04-19
  • 1970-01-01
  • 1970-01-01
  • 2016-05-22
  • 2021-01-21
  • 1970-01-01
  • 2012-12-18
相关资源
最近更新 更多