我有这段代码:
ZonedDateTime t1 = ZonedDateTime.parse("2018-04-06T10:01:00.000+03:00");
ZonedDateTime t2 = ZonedDateTime.parse("2018-04-06T10:01:00.000-03:00");
System.out.println(t1.compareTo(t2));
结果是-1。我想它会将t1和t2转换为相同的时区然后进行比较。例如,在第一种情况下它将(可能)进行比较
t1 = 2018-04-06T07:01:00.000+00:00 to t2 = 2018-04-06T13:01:00.000+00:00
此案例按预期返回1
ZonedDateTime t1 = ZonedDateTime.parse("2018-04-06T17:01:00.000+03:00");
ZonedDateTime t2 = ZonedDateTime.parse("2018-04-06T10:01:00.000-03:00");
System.out.println(t1.compareTo(t2));
但是这一个(*)不返回0,它返回1:
ZonedDateTime t1 = ZonedDateTime.parse("2018-04-06T16:01:00.000+03:00");
ZonedDateTime t2 = ZonedDateTime.parse("2018-04-06T10:01:00.000-03:00");
System.out.println(t1.compareTo(t2));
我甚至尝试在解析字符串之后使用truncatedTo(ChronoUnit.MINUTES)
来忽略秒部分,但没有任何改变。
最感兴趣的是如果我将t1 / t2减少/增加一秒,结果将为-1
例如:
ZonedDateTime t1 = ZonedDateTime.parse("2018-04-06T16:01:00.000+03:00");
ZonedDateTime t2 = ZonedDateTime.parse("2018-04-06T10:01:01.000-03:00");
System.out.println(t1.compareTo(t2));
在我的用例中,所有用户输入时间都将以上述格式保存在许多ZoneOffset中,我有一些查询需要将其与服务器时间进行比较(忽略时间的秒数)。如果上面的情况(*),我如何得到t1等于t2?
答案 0 :(得分:7)
比较首先基于瞬间,然后是本地 日期时间,然后是区域ID,然后是年表。它是 "与
Comparable
定义的等号"一致。
compareTo
在超类ChronoZonedDateTime
中实现,这是我们通常不关心的类,但我们需要查找某些方法的文档。所以上面的引用来自那里。
因此,在两个ZonedDateTime
个对象表示同一时刻的情况下,t1
的本地时间是16:01,大于t2
的10:01。所以1是正确的和预期的结果。另一方面,如果瞬间仅相隔一秒 - 或仅为1纳秒 - 则优先,并且不比较当地时间。
我相信这解释了你观察到的行为。
该引用进一步暗示了为什么必须如此:假设比较两个具有相同时刻但不同时区的ZonedDateTime
个对象返回0.然后比较将不再与equals一致。这被认为是一个非常好的属性(虽然不是必需的)。
类
C
的自然顺序被认为与一致 等于当且仅当e1.compareTo(e2) == 0
具有相同的布尔值时 类e1.equals(e2)
的每个e1
和e2
的值为C
。
(引自Comparable
interface documentation)
因此,如果您只想比较时刻,有两种选择,具体取决于您对结果的偏好类型:
使用isBefore
,isAfter
或isEqual
:
ZonedDateTime t1 = ZonedDateTime.parse("2018-04-06T16:01:00.000+03:00");
ZonedDateTime t2 = ZonedDateTime.parse("2018-04-06T10:01:00.000-03:00");
System.out.println(t1.isBefore(t2));
System.out.println(t1.isAfter(t2));
System.out.println(t1.isEqual(t2));
输出:
false false true
答案 1 :(得分:2)
使用toInstant(),然后比较结果,如下所示:
ZonedDateTime t1 = ZonedDateTime.parse("2018-04-06T16:01:00.000+03:00");
ZonedDateTime t2 = ZonedDateTime.parse("2018-04-06T10:01:00.000-03:00");
System.out.println(t1.toInstant().compareTo(t2.toInstant()));