ZonedDateTime 比较:预期:[Etc/UTC],但原为:[UTC]
我正在比较两个似乎相等的日期,但它们包含不同的区域名称:一个是,另一个是。Etc/UTC
UTC
根据这个问题:UTC和Etc / UTC时区之间有区别吗? - 这两个区域是相同的。但是我的测试失败了:
import org.junit.Test;
import java.sql.Timestamp;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import static org.junit.Assert.assertEquals;
public class TestZoneDateTime {
@Test
public void compareEtcUtcWithUtc() {
ZonedDateTime now = ZonedDateTime.now();
ZonedDateTime zoneDateTimeEtcUtc = now.withZoneSameInstant(ZoneId.of("Etc/UTC"));
ZonedDateTime zoneDateTimeUtc = now.withZoneSameInstant(ZoneId.of("UTC"));
// This is okay
assertEquals(Timestamp.from(zoneDateTimeEtcUtc.toInstant()), Timestamp.from(zoneDateTimeUtc.toInstant()));
// This one fails
assertEquals(zoneDateTimeEtcUtc,zoneDateTimeUtc);
// This fails as well (of course previous line should be commented!)
assertEquals(0, zoneDateTimeEtcUtc.compareTo(zoneDateTimeUtc));
}
}
结果:
java.lang.AssertionError:
Expected :2018-01-26T13:55:57.087Z[Etc/UTC]
Actual :2018-01-26T13:55:57.087Z[UTC]
更具体地说,我期望,这将等于,但他们不是!ZoneId.of("UTC")
ZoneId.of("Etc/UTC")
正如@NicolasHenneaux建议的那样,我应该使用方法。这是个好主意,但返回值,因为内部有这个实现:compareTo(...)
zoneDateTimeEtcUtc.compareTo(zoneDateTimeUtc)
-16
ZoneDateTime
cmp = getZone().getId().compareTo(other.getZone().getId());
断言结果:
java.lang.AssertionError:
Expected :0
Actual :-16
因此,问题在于实施中的某个地方。但我仍然期望,如果两个区域ID都有效并且都指定了相同的区域,那么它们应该是相等的。ZoneId
我的问题是:这是一个库错误,还是我做错了什么?
更新
有几个人试图说服我这是一种正常的行为,并且比较方法的实现使用id表示是正常的。在这种情况下,我应该问,为什么下面的测试运行正常?String
ZoneId
@Test
public void compareUtc0WithUtc() {
ZonedDateTime now = ZonedDateTime.now();
ZoneId utcZone = ZoneId.of("UTC");
ZonedDateTime zonedDateTimeUtc = now.withZoneSameInstant(utcZone);
ZoneId utc0Zone = ZoneId.of("UTC+0");
ZonedDateTime zonedDateTimeUtc0 = now.withZoneSameInstant(utc0Zone);
// This is okay
assertEquals(Timestamp.from(zonedDateTimeUtc.toInstant()), Timestamp.from(zonedDateTimeUtc0.toInstant()));
assertEquals(0, zonedDateTimeUtc.compareTo(zonedDateTimeUtc0));
assertEquals(zonedDateTimeUtc,zonedDateTimeUtc0);
}
如果 与 相同,那么我看到两个选项:Etc/UTC
UTC
- compareTo/equals 方法不应使用 ZoneId id,而应比较其规则
-
Zone.of(...)
已损坏,应将其视为相同的时区。Etc/UTC
UTC
否则我不明白为什么,工作正常。UTC+0
UTC
更新-2我报告了一个错误,ID:9052414。将看到甲骨文团队将决定什么。
更新-3错误报告被接受(不知道他们会不会将其关闭为“不会修复”):https://bugs.openjdk.java.net/browse/JDK-8196398