ทำไม
ZonedDateTime now = ZonedDateTime.now();
System.out.println(now.withZoneSameInstant(ZoneOffset.UTC)
.equals(now.withZoneSameInstant(ZoneId.of("UTC"))));
พิมพ์ออกมาfalse?
ฉันคาดหวังว่าทั้งสองZonedDateTimeอินสแตนซ์จะเท่ากัน
ทำไม
ZonedDateTime now = ZonedDateTime.now();
System.out.println(now.withZoneSameInstant(ZoneOffset.UTC)
.equals(now.withZoneSameInstant(ZoneId.of("UTC"))));
พิมพ์ออกมาfalse?
ฉันคาดหวังว่าทั้งสองZonedDateTimeอินสแตนซ์จะเท่ากัน
คำตอบ:
คำตอบมาจากjavadoc ของZoneId (เน้นของฉัน) ...
ZoneId ใช้เพื่อระบุกฎที่ใช้ในการแปลงระหว่าง Instant และ LocalDateTime ID มีสองประเภทที่แตกต่างกัน:
- ออฟเซ็ตคงที่ - ออฟเซ็ตที่ได้รับการแก้ไขอย่างสมบูรณ์จาก UTC / Greenwich ซึ่งใช้ออฟเซ็ตเดียวกันสำหรับวันที่ - เวลาท้องถิ่นทั้งหมด
- ภูมิภาคทางภูมิศาสตร์ - พื้นที่ที่ใช้ชุดกฎเฉพาะสำหรับการหาค่าชดเชยจาก UTC / Greenwich
ออฟเซ็ตคงที่ส่วนใหญ่แสดงโดย ZoneOffset การเรียก normalized () บน ZoneId ใด ๆ จะทำให้แน่ใจว่า ID ออฟเซ็ตคงที่จะแสดงเป็น ZoneOffset
... และจากjavadoc ของZoneId#of (เน้นของฉัน):
วิธีนี้จะแยกวิเคราะห์ ID ที่สร้าง ZoneId หรือ ZoneOffset ZoneOffset ถูกส่งกลับถ้า ID คือ 'Z' หรือเริ่มต้นด้วย '+' หรือ '-'
รหัสอาร์กิวเมนต์ถูกระบุเป็น"UTC"ดังนั้นมันจะส่งคืน a ZoneIdพร้อมกับออฟเซ็ตซึ่งนำเสนอในรูปแบบสตริงด้วย:
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จะส่งคืนtrueเนื่องจากnormalized()จะส่งคืนค่าที่เกี่ยวข้องZoneOffset:
ปรับรหัสโซนเวลาให้เป็นปกติโดยส่งคืน ZoneOffset หากเป็นไปได้
now.withZoneSameInstant(ZoneOffset.UTC)
.equals(now.withZoneSameInstant(ZoneId.of("UTC").normalized())); // true
ตามที่ระบุในเอกสารหากคุณใช้"Z"หรือ"+0"เป็นรหัสอินพุต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
ZoneId.of("Z")ให้คุณZoneOffset.UTCแต่ZoneId.of("UTC")ให้ZoneId(นั่นไม่ใช่ZoneOffset.UTC) API นี้ไม่ใช้งานง่ายพูดน้อยที่สุด