当前位置: 首页 > 面试题库 >

为什么ZoneOffset.UTC!= ZoneId.of(“ UTC”)?

慕容铭
2023-03-14
问题内容

为什么

ZonedDateTime now = ZonedDateTime.now();
System.out.println(now.withZoneSameInstant(ZoneOffset.UTC)
        .equals(now.withZoneSameInstant(ZoneId.of("UTC"))));

打印出来false

我希望两个ZonedDateTime实例都相等。


问题答案:

答案来自(强调我的)javadocZoneId

ZoneId用于标识用于在Instant和LocalDateTime之间进行转换的规则。有两种不同的ID类型:

  • 固定偏移量-与UTC /格林威治标准时间完全抵消的偏移量,所有本地日期时间都使用相同的偏移量
  • 地理区域-适用于从UTC /格林威治中查找偏移量的一组特定规则的区域

大多数固定偏移量由ZoneOffset表示。
在任何ZoneId上调用normalized()将确保将固定的偏移量ID表示为ZoneOffset。

…并且来自(强调我的)的javadocZoneId#of

此方法解析ID,产生ZoneId或ZoneOffset。 如果ID为’Z’或以’+’或’-‘开头,则返回ZoneOffset

参数id指定为"UTC",因此它将返回ZoneId带有偏移量的a ,该偏移量也以字符串形式表示:

System.out.println(now.withZoneSameInstant(ZoneOffset.UTC));
System.out.println(now.withZoneSameInstant(ZoneId.of("UTC")));

输出:

2017-03-10T08:06:28.045Z
2017-03-10T08:06:28.045Z[UTC]

使用equals比较方法时,将 检查对象是否相等 。由于存在上述差异,因此评估结果为false

当按照normalized()文档中的建议使用方法时,使用的比较equals将返回truenormalized()并将返回对应的ZoneOffset

标准化时区ID,并在可能的情况下返回ZoneOffset。

now.withZoneSameInstant(ZoneOffset.UTC)
    .equals(now.withZoneSameInstant(ZoneId.of("UTC").normalized())); // true

如文档所述,如果您使用"Z""+0"作为输入ID,of则将ZoneOffset直接返回,而无需调用normalized()

now.withZoneSameInstant(ZoneOffset.UTC).equals(now.withZoneSameInstant(ZoneId.of("Z"))); //true
now.withZoneSameInstant(ZoneOffset.UTC).equals(now.withZoneSameInstant(ZoneId.of("+0"))); //true

要检查 它们是否存储相同的日期时间
,可以改用isEqual方法

now.withZoneSameInstant(ZoneOffset.UTC)
    .isEqual(now.withZoneSameInstant(ZoneId.of("UTC"))); // true

样品

System.out.println("equals - ZoneId.of(\"UTC\"): " + nowZoneOffset
        .equals(now.withZoneSameInstant(ZoneId.of("UTC"))));
System.out.println("equals - ZoneId.of(\"UTC\").normalized(): " + nowZoneOffset
        .equals(now.withZoneSameInstant(ZoneId.of("UTC").normalized())));
System.out.println("equals - ZoneId.of(\"Z\"): " + nowZoneOffset
        .equals(now.withZoneSameInstant(ZoneId.of("Z"))));
System.out.println("equals - ZoneId.of(\"+0\"): " + nowZoneOffset
        .equals(now.withZoneSameInstant(ZoneId.of("+0"))));
System.out.println("isEqual - ZoneId.of(\"UTC\"): "+ nowZoneOffset
        .isEqual(now.withZoneSameInstant(ZoneId.of("UTC"))));

输出:

equals - ZoneId.of("UTC"): false
equals - ZoneId.of("UTC").normalized(): true
equals - ZoneId.of("Z"): true
equals - ZoneId.of("+0"): true
isEqual - ZoneId.of("UTC"): true


 类似资料:
  • 版本: 返回一个,其ID为“z”,偏移量为0,默认区域规则。 返回一个,包含ID“utc”和。 例如,在处理时。在这里,我能发现的唯一区别是它的打印方式不同。 我们正在来回地进行代码审查讨论,所以我想这种冲突并不罕见。 它是一个常量(此外,它的偏移量值(0)甚至被缓存)。 由于缺少区域信息,它的开销少了一点。 在UTC时,不需要考虑夏时制时间或历史变化,就像在任何其他时区一样。 因此,对于我迄今为

  • 我希望这两个实例是相等的。

  • 问题内容: 在Java 8中,我们有类,它奇怪地有一个方法 因此,您可能希望它实现接口,而该接口正是需要此方法,但事实并非如此。 当我想使用foreach循环遍历Stream时,我必须做类似的事情 我在这里想念什么吗? 问题答案: 人们已经在邮件列表 asked 上问过同样的问题。主要原因是Iterable也具有可重复的语义,而Stream没有。 我认为主要原因是Iterable暗示可重用性,而S

  • 这是我代码的简化版本: 是在第二次迭代后停止的协程。 是一个异步生成器,它在异步上下文管理器中生成数字。 输出为: 其实我有两个问题: 据我所知,AsyncIO将在事件循环的下一个周期中很快调用一个任务,并为执行提供了机会。但打印行(“该行未执行”)未执行。为什么?假设如果我们在

  • 问题内容: 我是一名即将毕业的计算机科学专业的学生,​​在我的整个编码生涯中,我发现很少使用枚举的实例,除了典型的情况(例如代表标准纸牌的面孔)外,还使用了枚举。 您是否知道在日常编码中使用枚举的任何巧妙方法? 为什么枚举如此重要,在什么情况下应该能够确定建立枚举是最佳方法? 问题答案: 这些是主要的论点,以及短的例子。 的情况 从Java 6开始,是一个凌乱类的示例,该类可以从使用中受益匪浅(除

  • Bootstrapping(引导) 是 Netty 中配置程序的过程,当你需要连接客户端或服务器绑定指定端口时需要使用 Bootstrapping。 如前面所述,Bootstrapping 有两种类型,一种是用于客户端的Bootstrap,一种是用于服务端的ServerBootstrap。不管程序使用哪种协议,无论是创建一个客户端还是服务器都需要使用“引导”。 面向连接 vs. 无连接 请记住,这