ทำไม
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 นี้ไม่ใช้งานง่ายพูดน้อยที่สุด