[英]java 8 - ZonedDateTime not equal another ZonedDateTime
我創建了兩個 ZonedDateTime 對象,我認為它們應該相等:
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.ZoneOffset ,在第二個 java.time.ZoneRegion 中,這使得 ZonedDateTime 對象不相等。 這令人困惑......有任何想法嗎?
您正在檢查評估為false
對象相等性,因為這些對象不相等。 一個綁定到ZoneId
,另一個綁定到ZoneOffset
。 如果你想檢查它們是否代表同一時間,你可以使用不太直觀的命名方法isEqual
。
例如:
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));
印刷:
isEqual:true
equals: false
順便說一句,請注意,對於已經知道為非null
兩個對象,您不需要使用Objects.equals(a,b)
。 您可以直接調用a.equals(b)
。
當使用 Jackson 序列化/反序列化 ZonedDateTime 的實例,然后將它們相互比較以驗證我的代碼是否正常工作時,這也讓我困擾了幾個小時。 我不完全理解其中的含義,但我所學到的只是使用 isEqual 而不是 equals。 但這會給測試計划帶來很大的麻煩,因為大多數斷言實用程序只會調用標准的 .equals()。
這是我在掙扎了一段時間后終於想出的:
@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");
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.