Bei der Berechnung von Jahren zwischen zwei Daten, wobei das zweite Datum aus dem ersten berechnet wird (dies ist ein vereinfachtes Beispiel dessen, woran ich gerade arbeite), scheinen LocalDate
und Period
ein Jahr etwas anders zu berechnen.
Zum Beispiel
%Vor%während
%Vor% Obwohl Sie explizit ein Jahr hinzugefügt haben, geben zuerst Period
die Jahre als 0
zurück, während der zweite Fall 1
zurückgibt.
Gibt es einen schönen Weg dahin?
Diese Frage hat eine philosophische Natur und umfasst wenige Probleme wie Zeitmessungen und Konventionen für Datumsformate.
LocalDate
ist eine Implementierung des ISO 8601 Datumsaustauschstandards.
Java Doc gibt explizit an, dass diese Klasse keine Zeit darstellt, sondern nur die Standarddatumsnotation bereitstellt.
Die API bietet nur einfache Operationen für die Notation selbst, und alle Berechnungen werden durchgeführt, indem das Jahr oder Monat oder Tag erhöht wird ein bestimmtes Datum.
Mit anderen Worten: Wenn Sie LocalDate.plusYears()
aufrufen, fügen Sie konzeptionelle Jahre mit jeweils 365 Tagen statt der genauen Zeit innerhalb eines Jahres hinzu.
Dies macht Tag die niedrigste Zeiteinheit, die Sie zu einem Datum hinzufügen können, das durch LocalDate
ausgedrückt wird.
Nach menschlichem Verständnis ist Datum kein Moment, sondern eine Periode.
Es beginnt mit 00h 00m 00s (...) und endet mit 23h 59m 59s (...).
LocalDate
vermeidet jedoch Probleme der Zeitmessung und der Ungenauigkeit menschlicher Zeiteinheiten ( Stunde , Tag , Monat und ) > Jahr können alle unterschiedlich lang sein) und modelliert die Datumsschreibweise einfach als Tupel von:
(years, months within a year, days within a month )
seit Beginn der Ära berechnet.
In dieser Interpretation macht es Sinn, dass Tag die kleinste Einheit ist, die das Datum beeinflusst.
Als Beispiel folgt:
%Vor%gibt
zurück %Vor% ... was zeigt, dass mit LocalDate
und der Anzahl der Sekunden (oder kleineren Einheiten, um die Genauigkeit zu steuern), die in Ihrer Frage angegebene Einschränkung nicht überwunden werden konnte.
Wenn Sie sich die Implementierung ansehen, finden Sie LocalDate.plusYears()
nach dem Hinzufügen der Jahre, Aufrufe resolvePreviousValid()
. Diese Methode überprüft dann das Schaltjahr und ändert das Feld Tag wie folgt:
day = Math.min(day, IsoChronology.INSTANCE.isLeapYear((long)year)?29:28);
Mit anderen Worten korrigiert es es, indem es effektiv 1 Tag abzieht.
Sie könnten Year.length()
verwenden, das die Anzahl der Tage für ein bestimmtes Jahr zurückgibt und für Schaltjahre 366 zurückgibt. So könnten Sie tun:
Sie werden immer noch auf folgende Kuriositäten stoßen (Aufruf von Year.length()
ersetzt durch die Anzahl der Tage für die Kürze):
gibt
zurück %Vor%dann
%Vor%gibt
zurück %Vor%und schließlich:
%Vor%gibt zurück:
%Vor%Beachten Sie, dass das Verschieben des Datums um 366 anstelle von 365 Tagen den Zeitraum von 11 Monaten und 30 Tagen auf 1 erhöht hat Jahr und 1 Tag (2 Tage mehr!).