Wie kann man in Java Differenzen zwischen zwei Datumsangaben berechnen?

Der Umgang mit Datumsberechnungen ist in Java bis zur Version 7 nicht sehr glücklich gelöst. Bei diesen Versionen ist es sinnvoll mit der Joda-Bibliothek zu arbeiten. Ab Java 8 stehen auch in den Java Core-Libs durch die Date-Time-API Klassen bereit, die z.B. Datums-Berechnungen erlauben, die bislang nur mit der Joda-Bibliothek einigerma├čen komfortabel erledigt werden konnten.
Im ersten Beispiel wird demonstriert, wie die verbleibenden Monate und Tage bis zum Weihnachtsfest des aktuellen Jahres mit der Joda-Bibliothek berechnet werden können, im zweiten, wie sich dies mit Java 8 gestaltet.

Die Joda-Bibliothek muss zunächst in der aktuellen Version unter http://joda-time.sourceforge.net/index.html heruntergeladen und wie unter Bibliothek einbinden erläutert in den Classpath eingebunden werden.

Zu Beginn werden zwei Objekte des Typs LocalDate erzeugt. Die Klasse liefert Datums-Objekte ohne Angabe einer bestimmten Zeitzone. Wird der Konstruktor ohne Parameter aufgerufen, repräsentiert das Objekt das aktuelle Datum. Alternativ kann der mehrfach überladene Konstruktor wie im zweiten Fall auch mit numerischen Angaben zum Jahr, Monat und Tag aufgerufen werden.
Der Vergleich findet durch die Erzeugung eines Period -Objektes statt, das ein Feld mit zeitlichen Intervall-Einheiten, wie Stunden, Wochen, Jahren, etc. enthalten kann. Die genaue Art der Intervalle wird durch eine statische Methode des Typs PeriodType bestimmt, die als dritter Parameter dem Period -Konstruktior übergeben wird. Durch entsprechende Getter-Methoden können die Intervalle als Integer-Werte ausgelesen werden.

Der verbleibende Quelltext steht im Dienste der Ausgabe: Zunächst werden die Intervall-Bezeichner daraufhin überprüft, ob ihr zugeordneter numerischer Wert nicht gleich 0 ist. Ist dies nicht der Fall wird der Bezeichner sprachlich angepasst. Dann klärt die Methode compareTo() der Klasse LocalDate welches der beiden Daten größer ist und passt die Ausgabe entsprechend an.

import org.joda.time.LocalDate;
import org.joda.time.Period;
import org.joda.time.PeriodType;

public class DatumsDifferenz {

    public static void main(String[] args) {
        LocalDate now = new LocalDate();
        LocalDate endDate = new LocalDate(now.year().get(), 12, 24);
        Period p = new Period(now, endDate, PeriodType.yearMonthDay());
        int y = p.getYears();
        int m = p.getMonths();
        int d = p.getDays();
        String yStr = y > 0 ? new Integer(y).toString()
                + (y > 1 ? " Jahren, " : " Jahr, ") : "";
        String mStr = m > 0 ? new Integer(m).toString()
                + (m > 1 ? " Monaten, " : " Monat, ") : "";
        String dStr = d > 0 ? new Integer(d).toString()
                + (d > 1 ? " Tagen" : " Tag") : "";
        int comp = endDate.compareTo(now);
        if (comp > 0)
            System.out
                    .println("Weihnachten ist in " + yStr + mStr + dStr + ".");
        else if (comp == 0)
            System.out.println("Heute ist Weihnachten.");
        else
            System.out.println("Weihnachten ist vorbei.");
    }
}

Beim Vergleich beider Quelltexte lässt sich erahnen, dass die Joda-Bibliothek f├╝r die Entwicklung der Date-Time-API Pate stand. Beide Quelltexte unterscheiden sich nur hinsichtlich einiger syntaktischer Elemente.

Das aktuelle Datum in Form eines LocalDate -Objektes wird nun durch Aufruf der statischen Methode now() erzeugt. Das Period -Objekt, das das Intervall zwischen Start- und Endzeitpunkt repräsentiert, wird nun statt durch den Konstruktor-Aufruf durch die statische Methode Period.between() erzeugt. Das sind auch schon die einzigen Unterschiede. Der Rest des Codes ist identisch mit dem obigen.

import java.time.LocalDate;
import java.time.Period;

public class DatumsDifferenz1 {

    public static void main(String[] args) {
        LocalDate now = LocalDate.now();
        LocalDate endDate = LocalDate.of(now.getYear(), 12, 24);
        Period p = Period.between(now, endDate);
        int y = p.getYears();
        int m = p.getMonths();
        int d = p.getDays();
        String yStr = y > 0 ? new Integer(y).toString()
                + (y > 1 ? " Jahren, " : " Jahr, ") : "";
        String mStr = m > 0 ? new Integer(m).toString()
                + (m > 1 ? " Monaten, " : " Monat, ") : "";
        String dStr = d > 0 ? new Integer(d).toString()
                + (d > 1 ? " Tagen" : " Tag") : "";
        int comp = endDate.compareTo(now);
        if (comp > 0)
            System.out
                    .println("Weihnachten ist in " + yStr + mStr + dStr + ".");
        else if (comp == 0)
            System.out.println("Heute ist Weihnachten.");
        else
            System.out.println("Weihnachten ist vorbei.");
    }
}