如何在java 8中比较两个java.time.Period?

时间:2016-12-25 11:06:46

标签: java date java-8 period

如何比较java 8中的两个句点?

E.g。

Period one = Period.of(10,0,0);
Period two = Period.of(8,0,0);

在这种情况下,一个大于两个。

6 个答案:

答案 0 :(得分:3)

由于未定义的一个月标准长度,两个Period对象的比较确实在一般情况下没有意义。

但是,在许多情况下,您可以很好地使用类似于后面的实现。合同将类似于compareTo()

的合同
public int comparePeriodsApproximately(Period p1, Period p2) {
    return period2Days(p1) - period2Days(p2);
}

private int period2Days(Period p) {
    if (p == null) {
        return 0;
    }
    return (p.getYears() * 12 + p.getMonths()) * 30 + p.getDays();
}

答案 1 :(得分:1)

JB Nizet正确地说。 您无法比较Periods,因为Period类中的java doc与java中可用的Period(Duration)类似,您可以使用它取决于您的业务需求。

"添加到ZonedDateTime时,持续时间和周期对夏令时的处理有所不同。持续时间将添加确切的秒数,因此一天的持续时间总是恰好24小时。相比之下,一个时期会增加一个概念日,试图维持当地时间。"

Period period = Period.of(10, 0, 0);
Period period2 = Period.of(10, 0, 0);

// No compareTo method in period
System.out.println(period.compareTo(period2));

Duration duration = Duration.ofDays(3);
Duration duration2 = Duration.ofDays(3);

// Can compare durations as it gives you the exact time
System.out.println(duration.compareTo(duration2));

答案 2 :(得分:1)

如果周期为months,周期为years,则可以执行以下操作:

Period periodOfMonths = Period.ofMonths(16);
Period periodOfYears = Period.ofYears(1);

// Check if period of months is ghreather that the period of years
System.out.println(periodOfMonths.toTotalMonths() > periodOfYears.toTotalMonths()); 

答案 3 :(得分:0)

我喜欢 Martin Cassidy 的回答,但建议使用硬编码的 LocalDate 而不是 LocalDate.now,例如 LocalDate.MIN

public static int compareTo(final Period first, final Period second)
{
    return LocalDate.MIN.plus(first).compareTo(LocalDate.MIN.plus(second));
}

答案 4 :(得分:0)

这个应该是防弹的。有用吗?

我声称,从 2097 年 2 月 1 日开始向前计数,从给定的年数和月数中获得尽可能少的天数,因为您第一次计算 2 月(28 天)并且需要很长时间才能获得两个连续 31 天(7 月和 8 月)的几个月,直到您遇到闰年(2104)为止。 2200 和 2300 也是非闰年,如果计数达到那么远。相反,从同一日期向后计数时,您会得到尽可能多的天数。您开始计算 2 个月 @ 31 天(一月和十二月)。你遇到的第一个二月是 2096 年,闰年,所以 29 天。而2000年是闰年。

所以我的技巧是从提到的日期开始计算两个时期之间的差异。如果计数一致认为差异为正(或负),那么无论我们从哪一天开始计数,two(或 one)将始终更长。

在某些情况下,计数会不一致。然后我拒绝了更长的时间。

    Period one = Period.of(10, 0, 0);
    Period two = Period.of(8, 0, 0);
    
    if (one.normalized().equals(two.normalized())) {
        System.out.println("They are the same.");
    } else {
        Period diff = two.minus(one);
        
        LocalDate anchor = LocalDate.of(2097, Month.FEBRUARY, 1);
        
        LocalDate plusDiff = anchor.plus(diff);
        LocalDate minusDiff = anchor.minus(diff);
        if (plusDiff.isAfter(anchor) && minusDiff.isBefore(anchor)) {
            System.out.println("Two is greater (unambiguously)");
        } else if (plusDiff.isBefore(anchor) && minusDiff.isAfter(anchor)) {
            System.out.println("One is greater (unambiguously)");
        } else {
            System.out.println("Cannot decide");
        }
    }

本例中的输出(使用问题中的句点):

<块引用>

一个更大(明确)

我在第一次比较中使用的 normalized 方法在年份和月份之间进行转换,确保月份在 -11 到 +11 的区间内并且与年份具有相同的符号(除非年份为 0 )。这可以明确地完成,因为一年总是有 12 个月。

您可以改进它以报告一个周期长于或等于另一个。例如,如果 one 是一个月而 two 是 31 天,我们知道 two 至少与 one 一样长,即使我们无法决定它是否是也严格更长。

答案 5 :(得分:-1)

这可以通过从compareTo()借用适当的LocalDate方法来完成。

public static int compareTo(final Period first, final Period second)
{
    final LocalDate now = LocalDate.now();
    return now.plus(first).compareTo(now.plus(second));
}