首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java8- ZonedDateTime不等于另一个ZonedDateTime

Java8- ZonedDateTime不等于另一个ZonedDateTime
EN

Stack Overflow用户
提问于 2014-09-11 17:28:12
回答 4查看 11.7K关注 0票数 16

我创建了两个ZonedDateTime对象,我认为它们应该是相等的:

代码语言:javascript
复制
public static void main(String[] args) {
    ZoneId zid = ZoneId.of("America/New_York");
    ZoneOffset offset = ZoneOffset.from(LocalDateTime.now().atZone(zid));
    ZonedDateTime zdt0 = ZonedDateTime.of(2014, 8, 24, 21, 10, 1, 777000002, offset);
    ZonedDateTime zdt1 = ZonedDateTime.of(2014, 8, 24, 21, 10, 1, 777000002, zid);
    boolean equals = Objects.equals(zdt0, zdt1);
    System.out.println("equals: " + equals);
}

在调试器中,我看到ZonedDateTime zone的类,在第一种情况下是,在第二种java.time.ZoneRegion中,这使得ZonedDateTime对象不相等。这很让人困惑..。有什么想法吗?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2014-09-11 18:09:12

您正在检查对象相等性,它的计算结果为false,因为这些对象不是等效的。一个绑定到一个ZoneId,另一个绑定到一个ZoneOffset。如果要检查它们是否表示相同的时间,则可以使用不太直观的方法isEqual

例如:

代码语言:javascript
复制
ZoneId zid = ZoneId.of("America/New_York");
ZoneOffset offset = ZoneOffset.from(LocalDateTime.now().atZone(zid));
ZonedDateTime zdt0 = ZonedDateTime.of(2014, 8, 24, 21, 10, 1, 777000002, offset);
ZonedDateTime zdt1 = ZonedDateTime.of(2014, 8, 24, 21, 10, 1, 777000002, zid);
System.out.println("isEqual:" + zdt0.isEqual(zdt1));
System.out.println("equals: " + zdt0.equals(zdt1));

指纹:

代码语言:javascript
复制
isEqual:true
equals: false

顺便说一句,请注意,对于两个您已经知道为非Objects.equals(a,b)的对象,不需要使用null。您可以直接调用a.equals(b)

票数 32
EN

Stack Overflow用户

发布于 2017-05-18 22:21:25

在使用Jackson序列化/反序列化ZonedDateTime实例并将它们与其他实例进行比较以验证代码是否正确运行时,这也对我造成了很大的影响。我不完全理解它的含义,但我学到的只是使用isEqual而不是等号。但是这给测试计划带来了很大的麻烦,因为大多数断言实用程序只会调用标准的.equals()。

经过一段时间的努力,我终于想出了一个办法:

代码语言:javascript
复制
@Test
public void zonedDateTimeCorrectlyRestoresItself() {

    // construct a new instance of ZonedDateTime
    ZonedDateTime now = ZonedDateTime.now(ZoneId.of("Z"));
    // offset = {ZoneOffset@3820} "Z"
    // zone   = {ZoneOffset@3820} "Z"

    String starting = now.toString();

    // restore an instance of ZonedDateTime from String
    ZonedDateTime restored = ZonedDateTime.parse(starting);
    // offset = {ZoneOffset@3820} "Z"
    // zone   = {ZoneOffset@3820} "Z"

    assertThat(now).isEqualTo(restored); // ALWAYS succeeds

    System.out.println("test");
}

@Test
public void jacksonIncorrectlyRestoresZonedDateTime() throws Exception {

    ObjectMapper objectMapper = new ObjectMapper();
    objectMapper.findAndRegisterModules();

    // construct a new instance of ZonedDateTime
    ZonedDateTime now = ZonedDateTime.now(ZoneId.of("Z"));
    // offset = {ZoneOffset@3820} "Z"
    // zone   = {ZoneOffset@3820} "Z"


    String converted = objectMapper.writeValueAsString(now);

    // restore an instance of ZonedDateTime from String
    ZonedDateTime restored = objectMapper.readValue(converted, ZonedDateTime.class);
    // offset = {ZoneOffset@3820} "Z"
    // zone   = {ZoneOffset@3821} "UTC"

    assertThat(now).isEqualTo(restored); // NEVER succeeds

    System.out.println("break point me");
}
票数 8
EN

Stack Overflow用户

发布于 2014-09-11 18:59:14

equals()方法在ZonedDateTime上要求对象的所有组件部分相等。由于ZoneOffset不等于ZoneRegion (尽管两者都是ZoneId的子类),该方法返回false。请阅读有关VALJO的文章,以更多地了解为什么以这种方式比较值类型。

isEqual方法只比较时间线上的瞬间,这可能是你想要的,也可能不是你想要的。您也可以使用timeLineOrder() 方法来比较两个ZoneDateTime,只使用时间线。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25793628

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档