Ich verwende Javas java.util.Date
Klasse in Scala und möchte ein Date
Objekt und die aktuelle Zeit vergleichen. Ich weiß, dass ich das Delta mit getTime () berechnen kann:
(new java.util.Date()).getTime() - oldDate.getTime()
Dies lässt mir jedoch nur long
Millisekunden. Gibt es einen einfacheren und schöneren Weg, um ein Zeitdelta zu erhalten?
Date
,Calendar
undSimpleDateFormat
“.java.time.Period
und / oderDuration
. Siehe die Antwort von Basil Bourque unten .Antworten:
Die JDK-
Date
API ist leider schrecklich kaputt. Ich empfehle die Verwendung der Joda Time Bibliothek .Joda Time hat ein Konzept des Zeitintervalls :
BEARBEITEN: Joda hat übrigens zwei Konzepte:
Interval
für die Darstellung eines Zeitintervalls zwischen zwei Zeitpunkten (repräsentieren die Zeit zwischen 8 und 10 Uhr) und einesDuration
, das eine Zeitspanne ohne die tatsächlichen Zeitgrenzen darstellt (z. B. zwei Stunden!)Wenn Sie sich nur für Zeitvergleiche interessieren,
Date
implementieren die meisten Implementierungen (einschließlich der JDK-Implementierung) eineComparable
Schnittstelle, über die Sie die verwenden könnenComparable.compareTo()
quelle
Comparable.compareTo()
nichtComparable.compare()
.java.time
Paket in Java 8 ist von Joda-Time inspiriert, jedoch kein Ersatz. Jeder hat seine Vor- und Nachteile. Zum Glück müssen Sie sich nicht zwischen ihnen entscheiden. Verwenden Sie jedes für seine Stärken, solange Sie mit Ihrenimport
Aussagen vorsichtig sind . Siehe diese andere Antwort zum Beispiel von java.time.Einfaches Diff (ohne lib)
Und dann können Sie anrufen:
um den Unterschied der 2 Daten in Minuten zu erhalten.
TimeUnit
istjava.util.concurrent.TimeUnit
eine Standard-Java-Aufzählung, die von Nanos bis zu Tagen reicht.Vom Menschen lesbarer Diff (ohne Bibliothek)
http://ideone.com/5dXeu6
Die Ausgabe ist so etwas wie
Map:{DAYS=1, HOURS=3, MINUTES=46, SECONDS=40, MILLISECONDS=0, MICROSECONDS=0, NANOSECONDS=0}
mit den bestellten Einheiten.Sie müssen diese Karte nur in eine benutzerfreundliche Zeichenfolge konvertieren.
Warnung
Die obigen Codefragmente berechnen einen einfachen Unterschied zwischen zwei Zeitpunkten. Es kann Probleme während eines Sommerzeitschalters verursachen, wie in diesem Beitrag erläutert . Dies bedeutet, wenn Sie den Unterschied zwischen Daten ohne Uhrzeit berechnen, fehlt möglicherweise ein Tag / eine Stunde.
Meiner Meinung nach ist der Datumsunterschied subjektiv, besonders an Tagen. Du darfst:
Zählen Sie die Anzahl der verstrichenen 24 Stunden: Tag + 1 - Tag = 1 Tag = 24 Stunden
Zählen Sie die Anzahl der verstrichenen Zeit und achten Sie dabei auf die Sommerzeit: Tag + 1 - Tag = 1 = 24 Stunden (bei Mitternacht und Sommerzeit können es jedoch 0 Tage und 23 Stunden sein).
Zählen Sie die Anzahl von
day switches
, dh Tag + 1 1 Uhr - Tag 11 Uhr = 1 Tag, auch wenn die verstrichene Zeit nur 2 Stunden beträgt (oder 1 Stunde, wenn eine Sommerzeit vorhanden ist: p).Meine Antwort ist gültig, wenn Ihre Definition des Datumsunterschieds an Tagen mit dem 1. Fall übereinstimmt
Mit JodaTime
Wenn Sie JodaTime verwenden, können Sie den Diff für 2 Instants (Millies Backed ReadableInstant) -Daten erhalten mit:
Sie können den Diff aber auch für lokale Daten / Zeiten abrufen:
quelle
Beachten Sie, dass dies mit UTC-Daten funktioniert. Wenn Sie sich die lokalen Daten ansehen, kann der Unterschied ein freier Tag sein. Und damit es mit lokalen Daten richtig funktioniert, ist aufgrund der Sommerzeit ein völlig anderer Ansatz erforderlich.
quelle
(endDate.getTime() - startDate.getTime())
, dassint
anstelle des Endergebnisses eine Umwandlung erfolgt und Sie einen ganzzahligen Überlauf erhalten.Verwenden des in Java 8+ integrierten java.time- Frameworks:
Ausgabe:
Weitere Informationen finden Sie im Oracle Tutorial und im ISO 8601- Standard.
quelle
Period
anstelle vonDuration
für Daten verwenden.Sie müssen Ihr Problem klarer definieren. Sie können einfach die Anzahl der Millisekunden zwischen den beiden
Date
Objekten nehmen und durch die Anzahl der Millisekunden in 24 Stunden dividieren, zum Beispiel ... aber:Date
ist immer in UTCquelle
tl; dr
Konvertieren Sie Ihre veralteten
java.util.Date
Objekte in deren Ersatzjava.time.Instant
. Berechnen Sie dann die verstrichene Zeit alsDuration
.ISO 8601 Format:
PnYnMnDTnHnMnS
Die sinnvolle Norm ISO 8601 definiert eine präzise Textdarstellung einer Zeitspanne als Anzahl von Jahren, Monaten, Tagen, Stunden usw. Die Norm nennt eine solche Zeitspanne eine Dauer . Das Format ist,
PnYnMnDTnHnMnS
wo dasP
Mittel "Punkt" bedeutet, dasT
den Datumsabschnitt vom Zeitabschnitt trennt und dazwischen Zahlen stehen, gefolgt von einem Buchstaben.Beispiele:
P3Y6M4DT12H30M5S
drei Jahre, sechs Monate, vier Tage, zwölf Stunden, dreißig Minuten und fünf Sekunden
PT4H30M
Viereinhalb Stunden
java.time
Das in Java 8 und höher integrierte Java.time- Framework ersetzt die problematischen alten
java.util.Date
/java.util.Calendar
Klassen. Die neuen Klassen sind von dem äußerst erfolgreichen Joda-Time- Framework inspiriert , das als Nachfolger gedacht ist. Das Konzept ist ähnlich, aber neu aufgebaut. Definiert durch JSR 310 . Erweitert um das ThreeTen-Extra- Projekt. Siehe das Tutorial .Moment
Die
Instant
Klasse repräsentiert einen Moment auf der Zeitachse in UTC mit einer Auflösung von Nanosekunden (bis zu neun (9) Stellen eines Dezimalbruchs).Vermeiden Sie am besten ältere Klassen wie
Date
/Calendar
. Wenn Sie jedoch mit altem Code interagieren müssen , der noch nicht auf java.time aktualisiert wurde , konvertieren Sie hin und her. Rufen Sie neue Konvertierungsmethoden auf, die den alten Klassen hinzugefügt wurden. Rufen Siejava.util.Date
anInstant
, um von a nach a zu wechselnDate::toInstant
.Zeitspanne
Die java.time-Klassen haben diese Idee, eine Zeitspanne als Anzahl von Jahren, Monaten, Tagen, Stunden, Minuten, Sekunden in zwei Hälften darzustellen, in zwei Hälften geteilt:
Period
seit Jahren, Monaten, TagenDuration
für Tage, Stunden, Minuten, SekundenHier ist ein Beispiel.
Dump zur Konsole.
Beide
Period
undDuration
verwenden den ISO 8601- Standard zum Generieren einer String-Darstellung ihres Werts.Java 9 fügt Methoden hinzu
Duration
, um den Tag-, Stunden-, Minuten- und Sekunden-Teil abzurufen.Sie können die Gesamtzahl der Tage oder Stunden oder Minuten oder Sekunden oder Millisekunden oder Nanosekunden in der gesamten Dauer abrufen.
In Java 9
Duration
erhält die Klasse neue Methoden zum Zurückgeben der verschiedenen Teile von Tagen, Stunden, Minuten, Sekunden, Millisekunden / Nanosekunden. Rufen Sie dieto…Part
Methoden:toDaysPart()
,toHoursPart()
, und so weiter.ChronoUnit
Wenn Sie sich nur für eine einfachere, größere Zeitgranularität interessieren, z. B. "Anzahl der verstrichenen Tage", verwenden Sie die
ChronoUnit
Aufzählung.Ein anderes Beispiel.
Über java.time
Das java.time- Framework ist in Java 8 und höher integriert. Diese Klassen verdrängen die lästigen alten Legacy - Datum-Zeit - Klassen wie
java.util.Date
,Calendar
, &SimpleDateFormat
.Das Joda-Time- Projekt, das sich jetzt im Wartungsmodus befindet , empfiehlt die Migration zu java.time.
Weitere Informationen finden Sie im Oracle-Lernprogramm . Suchen Sie im Stapelüberlauf nach vielen Beispielen und Erklärungen. Die Spezifikation ist JSR 310 .
Woher bekomme ich die java.time-Klassen?
Das ThreeTen-Extra- Projekt erweitert java.time um zusätzliche Klassen. Dieses Projekt ist ein Testfeld für mögliche zukünftige Ergänzungen von java.time. Sie können einige nützliche Klassen hier wie finden
Interval
,YearWeek
,YearQuarter
, und mehr .Joda-Zeit
UPDATE: Das Joda-Time- Projekt befindet sich jetzt im Wartungsmodus. Das Team empfiehlt die Migration zu den Klassen java.time . Ich lasse diesen Abschnitt für die Geschichte intakt.
Die Joda-Time-Bibliothek verwendet für ihre Standardeinstellungen ISO 8601. Die
Period
Klasse analysiert und generiert diese PnYnMnDTnHnMnS-Zeichenfolgen.Rendert:
quelle
Period
,Duration
undChronoUnit
, drei Klassen , deren Zweck das Delta zwischen den Zeitpunkten ist die Bestimmung. Bitte geben Sie an, welche Teile meiner „Textwand“ irrelevant sind. Und Sie sagen zu Unrecht die Frage nach einem „Delta zwischen Datumsangaben“: Die Frage nach einem Delta zwischenDate
Objekten, bei denen es sich um Datums- und Uhrzeitmomente handelt, nicht um „Datumsangaben“, trotz der unglücklichen Benennung dieser Klasse.java.util.Date
in a konvertiertInstant
(einfach aufrufen.toInstant
). Und ich habe denMoment
Abschnitt hinzugefügt , um zu erklären. Sie haben ein Paar vonDate
Objekten erwähnt, aber tatsächlich verwendet die Frage nur ein einziges vorhandenesDate
Objekt und erfasst dann den aktuellen Moment, also habe ich dasselbe getan. Danke für die Rückmeldung! Tipp: Geben Sie die Verwendung aufDate
- Diese Legacy-Klassen sind wirklich ein schreckliches Durcheinander.https://www.joda.org/joda-time/faq.html#datediff
quelle
Eine etwas einfachere Alternative:
Was "schöner" betrifft: Nun, was genau brauchst du? Das Problem bei der Darstellung der Zeitdauer als Anzahl von Stunden und Tagen usw. besteht darin, dass dies aufgrund der Komplexität der Daten zu Ungenauigkeiten und falschen Erwartungen führen kann (z. B. können Tage aufgrund der Sommerzeit 23 oder 25 Stunden haben).
quelle
Die Verwendung des Millisekunden-Ansatzes kann in einigen Regionen zu Problemen führen.
Nehmen wir zum Beispiel, die Differenz zwischen den beiden Daten 24.03.2007 und 25.03.2007 sollte 1 Tag betragen.
Wenn Sie jedoch die Millisekunden-Route verwenden, erhalten Sie 0 Tage, wenn Sie dies in Großbritannien ausführen!
Eine bessere Möglichkeit, dies zu implementieren, ist die Verwendung von java.util.Calendar
quelle
Es gibt viele Möglichkeiten, wie Sie den Unterschied zwischen Datum und Uhrzeit feststellen können. Eine der einfachsten Möglichkeiten, die ich kenne, wäre:
Die print-Anweisung ist nur ein Beispiel - Sie können sie nach Ihren Wünschen formatieren.
quelle
Da alle Antworten hier korrekt sind, aber ältere Java- oder Drittanbieter-Bibliotheken wie joda oder ähnliches verwenden, werde ich einfach neue Java.time- Klassen in Java 8 und höher verwenden. Siehe Oracle Tutorial .
Verwenden Sie
LocalDate
undChronoUnit
:quelle
Das Subtrahieren der Daten in Millisekunden funktioniert (wie in einem anderen Beitrag beschrieben), aber Sie müssen HOUR_OF_DAY und nicht HOUR verwenden, wenn Sie die Zeitteile Ihrer Daten löschen:
quelle
Wenn Sie JodaTime oder ähnliches nicht verwenden möchten, ist die beste Lösung wahrscheinlich folgende:
Die Anzahl der ms pro Tag ist nicht immer gleich (aufgrund der Sommerzeit und der Schaltsekunden), liegt jedoch sehr nahe beieinander, und zumindest Abweichungen aufgrund der Sommerzeit werden über längere Zeiträume aufgehoben. Daher ergibt das Teilen und anschließende Runden ein korrektes Ergebnis (zumindest solange der verwendete lokale Kalender keine anderen seltsamen Zeitsprünge als Sommerzeit und Schaltsekunden enthält).
Beachten Sie, dass dies immer noch davon ausgeht
date1
unddate2
auf dieselbe Tageszeit eingestellt ist. Für verschiedene Tageszeiten müssten Sie zuerst definieren, was "Datumsunterschied" bedeutet, wie von Jon Skeet hervorgehoben.quelle
date1.getTime()
vsdate2.getTime()
. Wenn Sie also zwischen 2016-03-03 und 2016-03-31 unterscheiden, werden 27 Tage berechnet, während Sie 28 Tage möchten.Math.round()
in "realen" Kalendern sicher zu sein scheint. Entschuldigung für den Lärm.Schauen Sie sich Joda Time an , eine verbesserte Datums- / Uhrzeit-API für Java, die mit Scala problemlos funktionieren sollte.
quelle
Lassen Sie mich den Unterschied zwischen Joda-Intervall und Tagen zeigen:
quelle
Wenn Sie eine formatierte Rückgabezeichenfolge wie "2 Days 03h 42m 07s" benötigen, versuchen Sie Folgendes:
quelle
std
oben ist undefiniert.Hinweis: startDate und endDates sind -> java.util.Date
und Enddatum
Ähnlich wie bei Tagen können Sie auch Stunden, Minuten und Sekunden erhalten
quelle
Beispiel hier ansehen http://www.roseindia.net/java/beginners/DateDifferent.shtml Dieses Beispiel gibt Ihnen einen Unterschied in Tagen, Stunden, Minuten, Sekunden und Millisekunden :).
quelle
Verwenden Sie die GMT-Zeitzone, um eine Instanz des Kalenders abzurufen. Legen Sie die Zeit mithilfe der festgelegten Methode der Kalenderklasse fest. Die GMT-Zeitzone hat einen Offset von 0 (nicht wirklich wichtig) und ein Sommerzeit-Flag auf false gesetzt.
quelle
java.util.Date
usw. ist. Wenn Sie den Hack verwenden, um die Zeitzone auf GMT einzustellen, wird der Code unempfindlich gegenüber Sommerzeiteffekten.Der folgende Code kann Ihnen die gewünschte Ausgabe geben:
quelle
quelle
quelle
Date
, daher ist dieser Vergleich der beste, der unter den gegebenen Umständen erreicht werden kann.Das Beste ist
Diese Zahl ist die Anzahl der Millisekunden pro Tag.
Ein Datum und ein anderes Datum geben den Unterschied in Millisekunden an.
Sammeln Sie die Antwort in einer doppelten Variablen.
quelle
Hier ist eine korrekte Java 7-Lösung in O (1) ohne Abhängigkeiten.
quelle
Das ist wahrscheinlich der einfachste Weg, dies zu tun - vielleicht liegt es daran, dass ich schon seit einiger Zeit in Java (mit seinen zugegebenermaßen klobigen Datums- und Zeitbibliotheken) codiere, aber dieser Code sieht für mich "einfach und nett" aus!
Sind Sie mit der Rückgabe des Ergebnisses in Millisekunden zufrieden oder ist es Teil Ihrer Frage, dass Sie es lieber in einem anderen Format zurückgeben möchten?
quelle
Nicht mit der Standard-API, nein. Sie können Ihre eigenen machen, indem Sie so etwas tun:
Oder Sie können Joda verwenden :
quelle
Nur um die erste Frage zu beantworten:
Fügen Sie den folgenden Code in eine Funktion wie Long getAge () {} ein
Das Wichtigste dabei ist, beim Multiplizieren und Dividieren mit langen Zahlen zu arbeiten. Und natürlich der Offset, den Java in seiner Datumsrechnung anwendet.
:) :)
quelle
Da die Frage mit Scala markiert ist,
quelle
Nachdem Sie alle anderen Antworten durchgesehen haben, um den Java 7-Datumstyp beizubehalten, aber mit dem Java 8-Diff-Ansatz präziser / standardisierter zu sein,
quelle
Versuche dies:
Sie können die Zeichenfolge im Parameter parse () -Methoden bearbeiten.
quelle