Wie erhalte ich in Java den Sekundenunterschied zwischen zwei Daten?


77

Die Java-Klassenbibliothek hat eine Klasse namens DateTime. DateTime hat diese Methode:

int daysBetween(DateTime other)

Dies gibt die Anzahl der Tage zwischen diesem und dem Parameter zurück. Es gibt keine Methode

int secondsBetween(DateTime other)

was ich zufällig brauche. Gibt es eine Klasse, die DateTime ähnelt, aber eine solche Methode hat?



1
Wenn Sie auf Java 8 sind, haben Sie ein paar weitere Optionen, siehe stackoverflow.com/q/25747499/32453
Rogerdpack

Antworten:


182

Nicht vertraut mit DateTime ...

Wenn Sie zwei Daten haben, können Sie getTime aufrufen, um Millsekunden abzurufen, den Diff abzurufen und durch 1000 zu dividieren. Zum Beispiel

Date d1 = ...;
Date d2 = ...;
long seconds = (d2.getTime()-d1.getTime())/1000;

Wenn Sie Kalenderobjekte haben, können Sie anrufen

c.getTimeInMillis()

und mach das gleiche


2
Wenn der Zeitunterschied nicht so hoch ist - int Sekunden = (int) ((d2.getTime () - d1.getTime ()) / 1000);
Xdg

@sebrock - behoben, um Typ so lange anzuzeigen - Casting auf int wird für kleinere Mengen funktionieren
Scott Stanchfield

1
@Xdg Ich habe in letzter Zeit eine Benutzeroberfläche entworfen und bin auf dasselbe "Problem" gestoßen, Integer.MAX_VALUEkann aber in Sekunden fast 70 Jahre darstellen. Das hat mir gereicht.
Mike

Ich suche eine Antwort mit LocalDateTime.
John Merlino

12

Ich möchte die moderne Antwort geben. Die anderen Antworten waren in Ordnung, als diese Frage gestellt wurde, aber die Zeit vergeht. Heute empfehle ich Ihnen die Verwendung java.timeder modernen Java-API für Datum und Uhrzeit .

    ZonedDateTime aDateTime = ZonedDateTime.of(2017, 12, 8, 19, 25, 48, 991000000, ZoneId.of("Europe/Sarajevo"));
    ZonedDateTime otherDateTime = ZonedDateTime.of(2017, 12, 8, 20, 10, 38, 238000000, ZoneId.of("Europe/Sarajevo"));

    long diff = ChronoUnit.SECONDS.between(aDateTime, otherDateTime);
    System.out.println("Difference: " + diff + " seconds");

Dies druckt:

Difference: 2689 seconds

ChronoUnit.SECONDS.between()arbeitet mit zwei ZonedDateTimeObjekten oder zwei OffsetDateTimes, zwei LocalDateTimes usw.

Wenn Sie etwas anderes als nur die Sekunden benötigen, sollten Sie die DurationKlasse in Betracht ziehen :

    Duration dur = Duration.between(aDateTime, otherDateTime);
    System.out.println("Duration: " + dur);
    System.out.println("Difference: " + dur.getSeconds() + " seconds");

Dies druckt:

Duration: PT44M49.247S
Difference: 2689 seconds

Die erste der beiden Zeilen gibt die Dauer im ISO 8601-Format aus. Die Ausgabe bedeutet eine Dauer von 44 Minuten und 49,247 Sekunden.

Warum java.time?

Die Datein mehreren anderen Antworten verwendete Klasse ist längst veraltet. Joda-Time, das auch in einigen Fällen (und möglicherweise in der Frage) verwendet wird, befindet sich jetzt im Wartungsmodus. Es sind keine größeren Verbesserungen geplant, und die Entwickler empfehlen offiziell die Migration auf java.timeJSR-310, auch bekannt als JSR-310.

Frage: Kann ich die moderne API mit meiner Java-Version verwenden?

Wenn Sie mindestens Java 6 verwenden , können Sie.


Sehr unterschätzte Antwort. Jodatimes Berechnungen hier sind etwas chaotisch. Ist ChronoUnit.SECONDS.between(oldDate.toInstant(), newDate.toInstant())jedoch ziemlich leicht zu merken.
anon58192932

10

Du solltest tun

org.joda.time.Seconds.secondBetween(date1, date2)

3
Willkommen bei StackOverflow und vielen Dank für Ihren Beitrag. Dies wäre ein stärkerer Beitrag, wenn Sie erklären würden, warum dies der richtige Weg ist.
Phil

5
@ Divonas macht keinen Unterschied. Seine Notation bezieht sich ausdrücklich auf joda
Tim

1
Der korrekte Methodenname lautet 'second s Between'. Das heißt, dies ist der sauberste Weg, den ich mit org.joda.time.DateTime gefunden habe.
Thisismydesign

1
Wenn Sie die Ergebnisse als int möchten, sollten Sie getSeconds () für das Ergebnis aufrufen. Seconds.secondsBetween(start, end).getSeconds()
Thisismydesign

1
Ich denke, es gibt jetzt eine Java 8-Methode, die keine Jodatime erfordert. Ich bin auf der Suche danach.
anon58192932

7

Das sollte es tun:

Date a = ...;
Date b = ...;

Math.abs(a.getTime()-b.getTime())/1000;

Hier die entsprechende Dokumentation: Date.getTime () . Beachten Sie, dass dies nur für Daten nach dem 1. Januar 1970, 00:00:00 GMT funktioniert


Hmm, warum sollte das nur für Daten nach dem 1. Januar 1970 funktionieren? Vorher sind die Werte negativ, aber die Arithmetik arbeitet mit negativen Zahlen.
Jay

5

Es gibt keine Klasse wie DateTimein der Standard-Java SE-API. Obwohl es eine in der Joda-Zeit gibt, hat auch das keine daysBetweenMethode.

Mit der Standard-Java-API können Sie am einfachsten Sekunden zwischen zwei java.util.DateObjekten abrufen, indem Sie deren Zeitstempel subtrahieren und durch 1000 dividieren:

int secondsBetween = (date1.getTime() - date2.getTime()) / 1000;

3

Es wird nicht empfohlen, verstrichene Zeiten zu verwenden java.util.Dateoder System.currentTimeMillis()zu messen. Es ist nicht garantiert, dass diese Daten monoton sind, und es treten Änderungen auf, wenn die Systemuhr geändert wird (z. B. wenn sie vom Server korrigiert werden). Wahrscheinlich wird dies selten vorkommen, aber warum nicht eine bessere Lösung codieren, anstatt sich über möglicherweise negative oder sehr große Änderungen Gedanken zu machen?

Stattdessen würde ich empfehlen, zu verwenden System.nanoTime().

long t1 = System.nanoTime();
long t2 = System.nanoTime();

long elapsedTimeInSeconds = (t2 - t1) / 1000000000;

BEARBEITEN

Weitere Informationen zur Monotizität finden Sie in der Antwort auf eine verwandte Frage, die ich gestellt habe. NanoTime verwendet nach Möglichkeit eine monotone Uhr. Ich habe aber nur mit Windows XP, Java 1.6 getestet und die Uhr modifiziert, wobei nanoTimemonoton und monoton warcurrentTimeMillis nicht.

Auch aus Javas Echtzeit-Dokumenten :

F: 50. Wird die Zeit über die Echtzeituhr mit besserer Auflösung als die von System.nanoTime () zurückgegebene Zeit zurückgegeben?

Die Echtzeituhr und System.nanoTime () basieren beide auf demselben Systemaufruf und damit auf derselben Uhr.

Mit Java RTS basieren alle zeitbasierten APIs (z. B. Timer, periodische Threads, Terminüberwachung usw.) auf dem hochauflösenden Timer. Zusammen mit Echtzeitprioritäten können sie sicherstellen, dass der entsprechende Code zum richtigen Zeitpunkt für Echtzeitbeschränkungen ausgeführt wird. Im Gegensatz dazu bieten gewöhnliche Java SE-APIs nur wenige Methoden, die hochauflösende Zeiten verarbeiten können, ohne dass die Ausführung zu einem bestimmten Zeitpunkt garantiert ist. Die Verwendung von System.nanoTime () zwischen verschiedenen Punkten im Code zur Durchführung von Messungen der verstrichenen Zeit sollte immer genau sein.


Hmm, interessanter Beitrag. Was lässt Sie sagen, dass nanoTime keinen Uhrenaktualisierungen unterliegt? Ich sehe nichts in der Java-Dokumentation dazu. Ich sage nicht, dass Sie falsch liegen, ich muss mich fragen, ob Sie eine Referenz haben oder Experimente durchgeführt haben, um dies zu belegen.
Jay


2

Sie können es verwenden org.apache.commons.lang.time.DateUtils, um es sauberer zu machen:

(firstDate.getTime() - secondDate.getTime()) / DateUtils.MILLIS_PER_SECOND

0

Welche Klasse ? Meinen Sie die Joda DateTime- Klasse? In diesem Fall können Sie einfach getMillis()jeden aufrufen und die entsprechende Subtraktion / Skalierung durchführen.

Ich würde Joda übrigens für Datums- / Zeitarbeit empfehlen, da es eine nützliche und intuitive API und Thread-Sicherheit für Formatierungs- / Analyseoptionen bietet.


Das ist keine Standardbibliothek (weder Joda) noch besonders bekannt (im Gegensatz zu Joda)
Brian Agnew

0

Nur ein Hinweis: Wenn Sie die Differenz zwischen zwei java.util.Date berechnen, ist der Ansatz, beide Daten zu subtrahieren und durch 1000 zu dividieren, sinnvoll. Seien Sie jedoch besonders vorsichtig, wenn Sie Ihre java.util.Date-Referenz von einem Kalenderobjekt erhalten . In diesem Fall müssen Sie die Sommerzeit Ihrer TimeZone berücksichtigen, da eines der von Ihnen verwendeten Daten möglicherweise in einer Sommerzeit liegt.

Das wird auf Prasoons Link erklärt. Ich empfehle, sich etwas Zeit zu nehmen, um es zu lesen.


0

Verwenden Sie diese Methode:

private Long secondsBetween(Date first, Date second){
    return (second.getTime() - first.getTime())/1000;
}

2
Fügen Sie Ihrer Antwort bitte eine Erklärung hinzu.
Alex Char

Es ist klar, dass Sie zwei Daten senden müssen, ich meine, Datum initialDate = neues Datum () und Datum finalDate = neues Datum (). Wenn Sie also initialDate und finalDate senden, können Sie den Unterschied in Sekunden feststellen ... beide werden es sein "konvertiere" mit der Methode getTIme nach Long und schließlich bekommst du die Differenz geteilt durch 1000, um die Sekunden zu erhalten ... tolle Antwort übrigens!
Raul Guerrero vor
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.