java.time
Das Java.time- Framework in Java 8 und höher ersetzt die alten Klassen java.util.Date/.Calendar. Die alten Klassen haben sich als lästig, verwirrend und fehlerhaft erwiesen. Vermeide sie.
Der java.time Rahmen wird durch die sehr erfolgreiche inspiriert Joda-Time Bibliothek, definiert durch JSR 310 , durch das erweiterten ThreeTen-Extra - Projekt, und erklärte im Tutorial .
Instant
Die Instant
Klasse repräsentiert einen Moment auf der Zeitachse in UTC .
Das java.time-Framework hat eine Auflösung von Nanosekunden oder 9 Stellen einer Bruchsekunde. Millisekunden sind nur 3 Stellen einer Bruchsekunde. Da die Auflösung in Millisekunden üblich ist, enthält java.time eine praktische Factory-Methode.
long millisecondsSinceEpoch = 1446959825213L;
Instant instant = Instant.ofEpochMilli ( millisecondsSinceEpoch );
MillisekundenSeitEpoch: 1446959825213 ist sofort: 2015-11-08T05: 17: 05.213Z
ZonedDateTime
Um die aktuelle Woche und den aktuellen Monat zu berücksichtigen, müssen wir eine bestimmte Zeitzone anwenden.
ZoneId zoneId = ZoneId.of ( "America/Montreal" );
ZonedDateTime zdt = ZonedDateTime.ofInstant ( instant , zoneId );
In zoneId: America / Montreal heißt das: 2015-11-08T00: 17: 05.213-05: 00 [America / Montreal]
Halb offen
In der Datums- und Zeitarbeit verwenden wir üblicherweise den Half-Open-Ansatz, um eine Zeitspanne zu definieren. Der Anfang ist inklusive, während das Ende exklusiv ist . Anstatt zu versuchen, den letzten Sekundenbruchteil des Wochenendes (oder Monats) zu bestimmen, erhalten wir den ersten Moment der folgenden Woche (oder des folgenden Monats). So eine Woche läuft vom ersten Moment an von Montag und geht nach oben , aber nicht einschließlich dem ersten Moment des folgenden Montags.
Lassen Sie uns den ersten und letzten Tag der Woche. Das java.time-Framework enthält ein Tool dafür, die with
Methode und die ChronoField
Aufzählung.
Standardmäßig verwendet java.time den ISO 8601- Standard. Montag ist also der erste Tag der Woche (1) und Sonntag der letzte (7).
ZonedDateTime firstOfWeek = zdt.with ( ChronoField.DAY_OF_WEEK , 1 );
ZonedDateTime firstOfNextWeek = firstOfWeek.plusWeeks ( 1 );
Diese Woche läuft von: 2015-11-02T00: 17: 05.213-05: 00 [Amerika / Montreal] bis 2015-11-09T00: 17: 05.213-05: 00 [Amerika / Montreal]
Hoppla! Sehen Sie sich die Tageszeit für diese Werte an. Wir wollen den ersten Moment des Tages. Der erste Moment des Tages ist nicht immer 00:00:00.000
auf die Sommerzeit (DST) oder andere Anomalien zurückzuführen. Deshalb sollten wir java.time die Anpassung in unserem Namen vornehmen lassen. Dazu müssen wir die LocalDate
Klasse durchlaufen .
ZonedDateTime firstOfWeek = zdt.with ( ChronoField.DAY_OF_WEEK , 1 );
firstOfWeek = firstOfWeek.toLocalDate ().atStartOfDay ( zoneId );
ZonedDateTime firstOfNextWeek = firstOfWeek.plusWeeks ( 1 );
Diese Woche läuft von: 2015-11-02T00: 00-05: 00 [Amerika / Montreal] bis 2015-11-09T00: 00-05: 00 [Amerika / Montreal]
Und das Gleiche für den Monat.
ZonedDateTime firstOfMonth = zdt.with ( ChronoField.DAY_OF_MONTH , 1 );
firstOfMonth = firstOfMonth.toLocalDate ().atStartOfDay ( zoneId );
ZonedDateTime firstOfNextMonth = firstOfMonth.plusMonths ( 1 );
Dieser Monat läuft von: 2015-11-01T00: 00-04: 00 [Amerika / Montreal] bis 2015-12-01T00: 00-05: 00 [Amerika / Montreal]
YearMonth
Eine andere Möglichkeit, um festzustellen, ob sich zwei Momente im selben Monat befinden, besteht darin, nach demselben YearMonth
Wert zu suchen.
Nehmen wir zum Beispiel an thisZdt
und thatZdt
sind beide ZonedDateTime
Objekte:
boolean inSameMonth = YearMonth.from( thisZdt ).equals( YearMonth.from( thatZdt ) ) ;
Millisekunden
Ich empfehle dringend, Ihre Datums- und Zeitarbeit nicht in Millisekunden ab Epoche auszuführen. Das ist in der Tat die Art und Weise, wie Datums- und Zeitklassen intern arbeiten, aber wir haben die Klassen aus einem bestimmten Grund. Der Umgang mit einer Zählung aus der Epoche ist umständlich, da die Werte für den Menschen nicht verständlich sind und das Debuggen und Protokollieren schwierig und fehleranfällig ist. Und wie wir bereits gesehen haben, können unterschiedliche Auflösungen im Spiel sein. Alte Java-Klassen und die Joda-Time-Bibliothek verwenden Millisekunden, während Datenbanken wie Postgres Mikrosekunden verwenden und java.time jetzt Nanosekunden verwendet.
Würden Sie Text als Bits verarbeiten, oder lassen Sie sich Klassen wie String
, StringBuffer
und StringBuilder
solche Details behandeln?
Aber wenn Sie darauf bestehen, von einem ZonedDateTime
eine bekommen Instant
, und von diesem erhalten einen Millisekunden-count-from-Epoche. Beachten Sie jedoch, dass dieser Aufruf zu Datenverlust führen kann . Alle Mikrosekunden oder Nanosekunden, die Sie möglicherweise in Ihrem ZonedDateTime
/ Instant
haben, werden abgeschnitten (verloren).
long millis = firstOfWeek.toInstant().toEpochMilli();
Ü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
.
Weitere Informationen finden Sie im Oracle-Lernprogramm . Suchen Sie im Stapelüberlauf nach vielen Beispielen und Erklärungen. Die Spezifikation ist JSR 310 .
Das Joda-Time- Projekt, das sich jetzt im Wartungsmodus befindet , empfiehlt die Migration zu den Klassen java.time .
Sie können java.time- Objekte direkt mit Ihrer Datenbank austauschen . Verwenden Sie einen JDBC-Treiber, der mit JDBC 4.2 oder höher kompatibel ist . Keine Notwendigkeit für Zeichenfolgen, keine Notwendigkeit für java.sql.*
Klassen.
Woher bekomme ich die java.time-Klassen?
1
...