You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Scala中GMT与BST时区的ZonedDateTime转Instant后为何值相同?

问题:GMT与BST时区的ZonedDateTime转换Instant后值相同的疑惑

我遇到一个问题:拥有两个本地时间相同但时区分别为GMT和BST的ZonedDateTime对象,调用toInstant转换后得到了相同的Instant值。我原本预期转换后它们的值应该不同,因为这两个时间字符串代表不同时区的同一本地时间,不确定是库的bug还是自身代码问题。

复现代码(Scala)

import ...
import java.util.{Set => JavaSet}
val string2 = "Tue Feb 23 18:00:46 BST 2021" 
val string1 = "Tue Feb 23 18:00:46 GMT 2021" 
val timestampFormat: DateTimeFormatter = new DateTimeFormatterBuilder()
    .appendOptional(DateTimeFormatter.ISO_DATE_TIME)
    .appendOptional(DateTimeFormatter.ISO_INSTANT)
    .appendOptional(DateTimeFormatter.ISO_OFFSET_DATE_TIME)
    .appendOptional(DateTimeFormatter.ISO_ZONED_DATE_TIME)
    .appendOptional(DateTimeFormatter.RFC_1123_DATE_TIME)
    .appendPattern("EEE MMM ppd HH:mm:ss ")
    .appendZoneText(TextStyle.SHORT, JavaSet.of(ZoneId.of("Europe/London")))
    .appendPattern(" yyyy")
    .toFormatter(Locale.US)

val parsedZdt2: ZonedDateTime = ZonedDateTime.parse(string2, timestampFormat)
val parsedZdt1: ZonedDateTime = ZonedDateTime.parse(string1, timestampFormat)
println(parsedZdt1 == parsedZdt2)
println("parsedZdt1.toString: " + parsedZdt1.toString)
println("parsedZdt2.toString: " + parsedZdt2.toString)

代码执行输出

false
parsedZdt1.toString: 2021-02-23T18:00:46Z[GMT]
parsedZdt2.toString: 2021-02-23T18:00:46Z[Europe/London]

转换为Instant的代码与输出

代码

println(parsedZdt1.toInstant == parsedZdt2.toInstant)
println("parsedZdt1.toInstant.toString: " + parsedZdt1.toInstant.toString)
println("parsedZdt2.toInstant.toString: " + parsedZdt2.toInstant.toString)

输出

true
parsedZdt1.toInstant.toString: 2021-02-23T18:00:46Z
parsedZdt2.toInstant.toString: 2021-02-23T18:00:46Z

问题解答

1. 为何两个ZonedDateTime转换为Instant后值相同?

核心原因是2021年2月23日属于英国冬令时时段,此时欧洲/伦敦时区的实际偏移量与GMT一致(均为UTC+0)。

你的代码通过appendZoneText限制了解析时区只能是Europe/London,所以解析"BST"时,因为当前日期不在夏令时范围内,系统会自动将其映射为Europe/London时区的UTC+0偏移;而解析"GMT"时,直接对应UTC+0的时区偏移。

两个ZonedDateTime的本地时间相同,且UTC偏移量完全一致,转换为代表UTC时间线上固定点的Instant时,自然会得到同一个值。

2. 转换前的parsedZdt1和parsedZdt2是否代表同一时刻?

是的,它们代表完全相同的时刻。

虽然parsedZdt1的时区ID是GMT,parsedZdt2是Europe/London,但在2021年2月23日这个时间点,两个时区的实际偏移量都是UTC+0,结合相同的本地时间,对应的UTC时间(即Instant)完全一致。

至于parsedZdt1 == parsedZdt2返回false,是因为ZonedDateTime的equals方法会同时校验时区ID,GMT和Europe/London是不同的时区标识,所以对象本身不相等,但它们对应的实际时间点毫无差异。


内容的提问来源于stack exchange,提问作者Adrian Qin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 05:18:16