Tl;dr
zum Beispiel, wenn die Startzeit 23:00 und die Endzeit 1:00 ist, um eine Dauer von 2:00 zu erhalten.
Nicht möglich. Wenn Sie nur die Tageszeit haben, bleibt die Uhr um Mitternacht stehen. Wie können wir ohne den Kontext der Daten wissen, ob Sie 1 Uhr am nächsten Tag, in der nächsten Woche oder im nächsten Jahrzehnt meinen?
Von 23.00 Uhr auf 1.00 Uhr zu wechseln bedeutet also rückwärts in der Zeit 22 Stunden, wobei die Zeiger der Uhr gegen den Uhrzeigersinn laufen. Siehe das Ergebnis unten, ein negativ zweiundzwanzig Stunden.
Duration.between( // Represent a span of time a total number of seconds plus a fractional second in nanoseconds.
LocalTime.of( 23 , 0 ) , // A time-of-day without a date and without a time zone.
LocalTime.of( 1 , 0 ) // A time-of-day clock stops at midnight. So getting to 1 AM from 11 PM means going backwards 22 hours.
) // Return a `Duration` object.
.toString() // Generate a `String` representing this span of time using standard ISO 8601 format: PnYnMnDTnHnMnS
PT-22H
Die Überschreitung von Mitternacht erfordert neben der Tageszeit auch den größeren Kontext des Datums (siehe unten).
Wie kann ich in Java die verstrichene Zeit messen?
- Erfassen Sie den aktuellen Moment in UTC, mit [
Instant.now()
](https://docs.oracle.com/javase/10/docs/api/java/time/Instant.html#now()) .
- Halten Sie später einen weiteren solchen Moment fest.
- Übergeben Sie beides an
Duration.between
.
- (a) Aus dem Ergebnis
Duration
Objekts eine Anzahl von 24-Stunden-Tagen, Stunden, Minuten, Sekunden und Sekundenbruchteilen in Nanosekunden, indem Sie die verschiedenen to…Part
Methoden.
(b) Oder, rufen Sie an toString
zur Erzeugung einer String
in Standardformat ISO 8601 de PnYnMnDTnHnMnS
.
Beispielcode, der ein Paar von Instant
Objekte.
Duration.between( // Represent a span of time a total number of seconds plus a fractional second in nanoseconds.
then , // Some other `Instant` object, captured earlier with `Instant.now()`.
Instant.now() // Capture the current moment in UTC with a resolution as fine as nanoseconds, depending on the limits of your host computer hardware clock and operating system. Generally you will get current moment in microseconds (six decimal digits of fractional second) in Java 9, 10, and 11, but only milliseconds in Java 8.
) // Return a `Duration` object.
.toString() // Generate a `String` representing this span of time using standard ISO 8601 format: PnYnMnDTnHnMnS
PT3M27.602197S
Neue Technologie in Java 8+
Dafür gibt es jetzt eine neue Technologie, die in Java 8 und höher integriert ist, die java.time Rahmen.
java.time
Das java.time-Framework ist definiert durch JSR 310 , inspiriert von dem sehr erfolgreichen Joda-Time Projekt, erweitert um das DreiZehn-Extra Projekt, und beschrieben in der Oracle-Tutorial .
Die alten Datums-Zeit-Klassen wie java.util.Date/.Calendar, die mit den ersten Java-Versionen mitgeliefert wurden, haben sich als schlecht entworfen, verwirrend und problematisch erwiesen. Sie wurden durch die java.time-Klassen abgelöst.
Auflösung
Andere Antworten behandeln die Auflösung.
Die java.time-Klassen haben Nanosekunde Auflösung, bis zu neun Ziffern eines Dezimalbruchteils einer Sekunde. Zum Beispiel, 2016-03-12T04:29:39.123456789Z
.
Sowohl die alten java.util.Date/.Calendar-Klassen als auch die Joda-Time-Klassen haben eine Millisekunden-Auflösung (3 Ziffern des Bruches). Zum Beispiel, 2016-03-12T04:29:39.123Z
.
In Java 8 wird der aktuelle Zeitpunkt aufgrund eines Legacy-Problems nur mit einer Auflösung von bis zu einer Millisekunde abgerufen. In Java 9 und höher kann die aktuelle Zeit bis zu einer Nanosekunden-Auflösung ermittelt werden, sofern die Hardware-Uhr Ihres Computers so fein läuft.
Tageszeit
Wenn Sie wirklich nur mit der Uhrzeit arbeiten wollen, ohne ein Datum oder eine Zeitzone, verwenden Sie die LocalTime
Klasse.
LocalTime sooner = LocalTime.of ( 17, 00 );
LocalTime later = LocalTime.of ( 19, 00 );
A Duration
stellt eine Zeitspanne in Form einer Anzahl von Sekunden plus Nanosekunden dar.
Duration duration = Duration.between ( sooner, later );
Dump auf die Konsole.
System.out.println ( "sooner: " + sooner + " | later: " + later + " | duration: " + duration );
früher: 17:00 | später: 19:00 | Dauer: PT2H
ISO 8601
Beachten Sie die Standardausgabe von Duration::toString
ist im Standard ISO 8601 Format. In diesem Format werden die P
markiert den Anfang (wie in 'Punkt'), und das T
trennt den Teil Jahre-Monate-Tage vom Teil Stunden-Minuten-Sekunden.
Mitternachtsüberquerung
Leider wird die Arbeit mit der Uhrzeit erst dann kompliziert, wenn man die Uhr über Mitternacht hinaus umdreht. Die LocalTime
Klasse geht davon aus, dass Sie zu einem früheren Zeitpunkt des Tages zurückgehen wollen.
Mit dem gleichen Code wie oben, aber von 23:00
a 01:00
ergibt einen negativen Wert von zweiundzwanzig Stunden ( PT-22H
).
LocalTime sooner = LocalTime.of ( 23, 0 );
LocalTime later = LocalTime.of ( 1, 0 );
früher: 23:00 | später: 01:00 | Dauer: PT-22H
Datum-Uhrzeit
Wenn Sie beabsichtigen, Mitternacht zu überschreiten, ist es wahrscheinlich sinnvoller, mit Datums- und Uhrzeitwerten zu arbeiten als mit reinen Tageszeitwerten.
Zeitzone
Die Zeitzone ist für das Datum entscheidend. Wir geben also drei Punkte an: (1) das gewünschte Datum, (2) die gewünschte Uhrzeit und (3) die Zeitzone als Kontext, in dem wir das Datum und die Uhrzeit interpretieren. Hier wählen wir willkürlich die Zeitzone des Montréal Bereich.
Wenn Sie das Datum nur durch eine Abweichung von der UTC verwenden Sie eine ZoneOffset
mit einer OffsetDateTime
. Wenn Sie eine vollständige Zeitzone haben (Offset plus Regeln für die Behandlung von Anomalien wie Sommerzeit), verwenden Sie eine ZoneId
mit einer ZonedDateTime
.
LocalDate localDate = LocalDate.of ( 2016, 1, 23 );
ZoneId zoneId = ZoneId.of ( "America/Montreal" );
ZonedDateTime sooner = ZonedDateTime.of ( localDate, LocalTime.of ( 23, 0 ), zoneId );
Als späteren Zeitpunkt geben wir den nächsten Tag um 1:00 Uhr an.
ZonedDateTime later = ZonedDateTime.of ( localDate.plusDays ( 1 ), LocalTime.of ( 1, 0 ), zoneId );
Wir berechnen die Duration
auf die gleiche Weise wie oben beschrieben. Jetzt erhalten wir die zwei Stunden, die in dieser Frage erwartet werden.
Duration duration = Duration.between ( sooner, later );
Dump auf die Konsole.
System.out.println ( "sooner: " + sooner + " | later: " + later + " | duration: " + duration );
früher: 2016-01-23T23:00-05:00[Amerika/Montreal] | später: 2016-01-24T01:00-05:00[Amerika/Montreal] | Dauer: PT2H
Sommerzeit
Wenn es sich bei den vorliegenden Datumszeiten um Sommerzeit oder eine andere derartige Anomalie handelte, würden sich die java.time-Klassen nach Bedarf anpassen. Lesen Sie das Klassendokument für Details.
Über java.time
Die java.time Framework ist in Java 8 und höher integriert. Diese Klassen verdrängen die lästigen alten Erbe Datum-Zeit-Klassen wie java.util.Date
, Calendar
, & SimpleDateFormat
.
Die Joda-Time Projekt, jetzt in Wartungsmodus rät zur Migration auf den java.time Klassen.
Weitere Informationen finden Sie in der Oracle-Tutorial . Und suchen Sie auf Stack Overflow nach vielen Beispielen und Erklärungen. Spezifikation ist JSR 310 .
Sie können umtauschen java.time Objekte direkt mit Ihrer Datenbank. Verwenden Sie eine JDBC-Treiber übereinstimmend mit JDBC 4.2 oder später. Keine Notwendigkeit für Strings, keine Notwendigkeit für java.sql.*
Klassen.
Wo erhält man die java.time-Klassen?
- Java SE 8 , Java SE 9 , Java SE 10 und später
- Eingebaut.
- Teil der Standard-Java-API mit einer gebündelten Implementierung.
- Java 9 fügt einige kleinere Funktionen und Korrekturen hinzu.
- Java SE 6 y Java SE 7
- Ein Großteil der java.time-Funktionalität wurde in Java 6 und 7 zurückportiert in DreiZehn-Backport .
- Android
- Spätere Versionen von Android bündeln Implementierungen der java.time-Klassen.
- Bei älteren Android-Betriebssystemen (<26) ist die DreiZehnABP Projekt passt sich an DreiZehn-Backport (siehe oben). Siehe Wie benutzt man ThreeTenABP .
Die DreiZehn-Extra Projekt erweitert java.time um zusätzliche Klassen. Dieses Projekt dient als Versuchsfeld für mögliche zukünftige Erweiterungen von java.time. Sie finden hier vielleicht einige nützliche Klassen wie Interval
, YearWeek
, YearQuarter
und mehr .