Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to compare two Joda time Periods

Tags:

java

jodatime

It does not seem straighforward.

I am trying this:

@Override
public int compare(Period o1, Period o2) {
    return o1.toStandardDays().getDays() > o2.toStandardDays().getDays() ? -1 : (o1.toStandardDays().getDays() == o2.toStandardDays().getDays() ? 0 : 1);
}

But I get this exception:

java.lang.UnsupportedOperationException: Cannot convert to Days as this period contains months and months vary in length
    at org.joda.time.Period.checkYearsAndMonths(Period.java:1455)
    at org.joda.time.Period.toStandardDays(Period.java:1314)

I hoped Peroid would have an isLongerThan(Period p) method.

like image 976
Persimmonium Avatar asked Jun 24 '11 12:06

Persimmonium


3 Answers

From the Joda Documentation:

To compare the actual duration of two periods, convert both to durations using toDuration, an operation that emphasises that the result may differ according to the date you choose.

The two toDuration methods are BasePeriod#toDurationTo(ReadableInstant) and BasePeriod#toDurationFrom(ReadableInstant). This means that you must choose either a start or end instant of this period in order to be able to compute its duration.

If that is a problem for you, then you might want to directly use Duration instead of Period.

like image 180
Matt Ball Avatar answered Oct 16 '22 15:10

Matt Ball


As Matt Ball also explained in his answer, to compare 2 periods you need to convert them to a duration first. Durations are relative to a certain point in time, so you need to do something like this:

public static boolean isLonger(Period p1, Period p2) {
   Instant now = Instant.now();
   Duration d1 = p1.toDurationTo(now);
   Duration d2 = p2.toDurationTo(now);
   return d1.isLongerThan(d2);
}

public static boolean isShorter(Period p1, Period p2) {
   Instant now = Instant.now();
   Duration d1 = p1.toDurationTo(now);
   Duration d2 = p2.toDurationTo(now);
   return d1.isShorterThan(d2);
}
like image 29
THelper Avatar answered Oct 16 '22 15:10

THelper


I wrote a method that should be able to compare two Periods to the nearest day (I didn't care about hours and minutes):

private int comparePeriods(Period period1, Period period2)
{
    if (period1.getYears() != period2.getYears())
    {
        return Integer.compare(period1.getYears(), period2.getYears());
    }
    if (period1.getMonths() != period2.getMonths())
    {
        return Integer.compare(period1.getMonths(), period2.getMonths());
    }
    if (period1.getWeeks() != period2.getWeeks())
    {
        return Integer.compare(period1.getWeeks(), period2.getWeeks());
    }
    if (period1.getDays() != period2.getDays())
    {
        return Integer.compare(period1.getDays(), period2.getDays());
    }
    return 0;
}

Note that this method expects both periods to be normalised or it will not give accurate results.

like image 44
Alex Spurling Avatar answered Oct 16 '22 16:10

Alex Spurling