ZonedDateTime
# 57.ZonedDateTime
LocalDateTime
总是表示本地日期和时间,ZonedDateTime
可以表示带时区的日期和时间,相当于 LocalDateTime
+ 时区的组合。
在 Java8 中新引入了一个时区类 ZoneId
,注意和旧的 java.util.TimeZone
区别。
ZonedDateTime
仍然提供了 plusDays()
等加减操作
# 基本使用
ZonedDateTime zb = ZonedDateTime.now(); //default Zone
ZonedDateTime zbNewYork = ZonedDateTime.now(ZoneId.of("America/New_York"));
System.out.println(zb);
System.out.println(zbNewYork);
1
2
3
4
2
3
4
输出:
2022-12-27T16:35:58.532+08:00[Asia/Shanghai]
2022-12-27T03:35:58.533-05:00[America/New_York]
1
2
2
时区不同,但表示的时间都是同一时刻(也就是说在上海时区的 2022 年 12 月 27 日 16:35:58 秒,这个时刻,在地球的另一端,纽约的本地时间为 2022 年 12 月 27 日 3:35:58 秒)
# LocalDateTime + ZoneId
给一个 LocalDateTime
附加一个 ZoneId
,就可以变成 ZonedDateTime
:
LocalDateTime dt = LocalDateTime.of(2022,5,21,8,35,0);
ZonedDateTime zb2 = dt.atZone(ZoneId.systemDefault());
ZonedDateTime zbNewYork2 = dt.atZone(ZoneId.of("America/New_York"));
System.out.println(zb2);
System.out.println(zbNewYork2);
1
2
3
4
5
2
3
4
5
输出:
2022-05-21T08:35+08:00[Asia/Shanghai]
2022-05-21T08:35-04:00[America/New_York]
1
2
2
注意,此时两个是不同的时刻了。虽然本地时间一样,但是时区不同。
# 转换时区
通过 withZoneSameInstant()
将关联时区转换到另一个时区,转换后日期和时间都会相应调整。
北京时间转为纽约时间:
ZonedDateTime zbShanghai = ZonedDateTime.now(ZoneId.of("Asia/Shanghai"));
ZonedDateTime zbNewWork = zbShanghai.withZoneSameInstant(ZoneId.of("America/New_York"));
System.out.println(zbShanghai);
System.out.println(zbNewWork);
1
2
3
4
2
3
4
2022-12-27T16:49:20.683+08:00[Asia/Shanghai]
2022-12-27T03:49:20.683-05:00[America/New_York]
1
2
2
要特别注意,时区转换的时候,由于夏令时的存在,不同的日期转换的结果很可能是不同的。涉及到时区时,千万不要自己计算时差,否则难以正确处理夏令时。
# 转为本地时间
可以将 ZonedDateTime
转为 LocalDateTime,这样会直接丢弃时区
LocalDateTime ldt = zdt.toLocalDateTime();
1
上次更新: 2024/10/1 16:19:31