【问题标题】:How to get the maximum of two ZonedDateTime instances?如何获得最多两个 ZonedDateTime 实例?
【发布时间】:2020-02-19 00:00:57
【问题描述】:

我有两个ZonedDateTime 实例:

final ZonedDateTime a = ...;
final ZonedDateTime b = ...;

我想获得这两个值的最大值。我想避免编写自定义的临时代码。

在 Java 8 中最好的方法是什么?我目前正在这样做:

final ZonedDateTime c = Stream.of(a, b).max(ChronoZonedDateTime::compareTo).get();

有更好的方法吗?

【问题讨论】:

    标签: java java-stream comparator date-comparison zoneddatetime


    【解决方案1】:

    您可以直接拨打isAfter:

    ZonedDateTime max = a.isAfter(b) ? a : b;
    

    或者因为类实现了Comparable

    a.compareTo(b);
    

    正如 OleV.V. 指出的那样。在 cmets 中,这是比较时间的两种方法之间的差异。因此,对于相同的值,它们可能会产生不同的结果

    DateTimeFormatter formatter = DateTimeFormatter.ISO_DATE_TIME;
    ZonedDateTime time1 = ZonedDateTime.from(formatter.parse("2019-10-31T02:00+01:00"));
    ZonedDateTime time2 = ZonedDateTime.from(formatter.parse("2019-10-31T01:00Z"));
    
    System.out.println(time1.isAfter(time2) + " - " + time1.isBefore(time1) + " - " + time1.isEqual(time2));
    System.out.println(time1.compareTo(time2));
    

    生成

    假-假-真
    1

    【讨论】:

    • 两者在极端情况下并不总是给出相同的结果。 isAfter 只比较时间、瞬间。如果时刻相等,compareTo 会继续比较当地时间。所以如果a2019-10-31T02:00+01:00[Europe/Stockholm]b2019-10-31T01:00Z[Europe/London],那么a.isAfter(b) 是假的,但a.compareTo(b) > 0 是真的。
    • @OleV.V.所以你说的是isAfter 更正确,因为它处理时区,而compareTo 如果你想独立于时区比较两个本地时间,则应该使用。
    • 不,@JoakimDanielson,不完全是。 compareTo 首先比较瞬间,所以如果两个对象表示不同的时间点(即使相隔仅 1 纳秒),它会按照您期望的方式工作。只有当它们表示相同的时间点时,它才会比较当地时间。因此,您的两个 sn-ps 都符合提问者所述的要求。只是他们断绝关系的方式不同。 (为了比较在其他答案中使用Collections.max如何打破平局,根本没有指定。)
    【解决方案2】:

    ZonedDateTime 实现了Comparable 接口,因此您可以简单地使用Collections.max

    Collections.max(Arrays.asList(a,b));
    

    【讨论】:

    • 这也是 Guava 所建议的。参见例如guava.dev/releases/23.0/api/docs/com/google/common/collect/…
    • @thatsme 该链接是使用上述方法而不是他们自己的类似方法的一般建议,并不特定于日期/时间比较。我看不出首先创建一个列表对象然后调用 compareTo 而不是直接调用 compareTo 更有效
    • @JoakimDanielson 对我来说,重点是调用名为 max 的方法更容易阅读。两种方法都是有效的,选择可能是个人喜好问题(我对这两个答案都投了赞成票)。
    猜你喜欢
    • 2019-02-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-02
    • 2021-09-21
    • 1970-01-01
    • 2019-12-11
    • 2018-02-15
    相关资源
    最近更新 更多