5.2Wichtige Datum-Klassen im Überblick
Weil Datumsberechnungen verschlungene Gebilde sind, können wir den Entwicklern von Java dankbar sein, dass sie uns viele Klassen zur Datumsberechnung und -formatierung beigelegt haben. Die Entwickler hielten die Klassen so abstrakt, dass lokale Besonderheiten wie Ausgabeformatierung, Parsen, Zeitzonen, Sommer- und Winterzeit unter verschiedenen Kalendern möglich sind.
Bis zur Java-Version 1.1 stand zur Darstellung und Manipulation von Datumswerten ausschließlich die Klasse java.util.Date zur Verfügung. Diese hatte mehrere Aufgaben:
Erzeugung eines Datum-Objekts aus Jahr, Monat, Tag, Minute und Sekunde
Abfrage von Tag, Monat, Jahr … mit der Genauigkeit von Millisekunden
Ausgabe und Verarbeitung von Datum-Zeichenketten
Da die Date-Klasse nicht ganz fehlerfrei und internationalisiert war, wurden im JDK 1.1 neue Klassen eingeführt:
Calendar nimmt sich der Aufgabe von Date an, zwischen verschiedenen Datumsrepräsentationen und Zeitskalen zu konvertieren. Die Unterklasse GregorianCalendar wird direkt erzeugt.
DateFormat zerlegt Datum-Zeichenketten und formatiert die Ausgabe. Auch Datum-Formate sind vom Land abhängig, das Java durch Locale-Objekte darstellt, und von einer Zeitzone, die durch die Exemplare der Klasse TimeZone repräsentiert ist.
In Java 8 ist eine weitere Datumsbibliothek mit ganz neuen Typen eingezogen. Endlich können auch Datum und Zeit getrennt repräsentiert werden:
LocalDate, LocalTime, LocalDateTime sind die temporalen Klassen für ein Datum, für eine Zeit und für eine Kombination aus Datum und Zeit.
Period und Duration stehen für Abstände.
5.2.1Der 1.1.1970
Der 1.1.1970 war ein Tag mit wegweisenden Änderungen. In der katholischen Kirche wurde der Allgemeine Römische Kalender eingeführt,[ 60 ](Cäsar und der julianische Kalender liegen noch weiter zurück.) und die Briten freuten sich, dass die Volljährigkeit von 24 Jahren auf 18 Jahre fiel. Auch für uns Java-Entwickler ist der 1.1.1970 von Bedeutung, denn viele Zeiten in Java sind relativ zu diesem Datum. Der Zeitstempel 0 bezieht sich auf den 1.1.1970 0:00:00 Uhr Greenwich-Zeit – das entspricht 1 Uhr nachts deutscher Zeit. Die Genauigkeit, in der Java zählt, liegt auf der Ebene von Millisekunden. So ist 0 der 1.1.1970, und 1273222647313 verweist auf den Vormittag des 7. Mai 2010.
5.2.2System.currentTimeMillis()
Die Anzahl der Millisekunden wird in einem long repräsentiert, also in 64 Bit. Das reicht für etwa 300 Millionen Jahre. Die Methode System.currentTimeMillis()liefert die vergangenen Millisekunden relativ zum 1.1.1970, wobei allerdings die Uhr des Betriebssystems nicht so genau gehen muss.
5.2.3Einfache Zeitumrechnungen durch TimeUnit
Eine Zeitdauer wird in Java oft durch Millisekunden ausgedrückt. 1.000 Millisekunden entsprechen 1 Sekunde, 1.000 × 60 Millisekunden 1 Minute usw. Diese ganzen großen Zahlen sind jedoch nicht besonders anschaulich, sodass zur Umrechnung TimeUnit-Objekte mit ihren toXXX(…)-Methoden genutzt werden.
Java deklariert folgende Konstanten in TimeUnit:
NANOSECONDS
MICROSECONDS
MILLISECONDS
DAYS
HOURS
SECONDS
MINUTES
Jedes der Aufzählungselemente definiert die Umrechnungsmethoden toDays(…), toHours(…), toMicros(…), toMillis(…), toMinutes(…), toNanos(…), toSeconds(…); sie bekommen ein long und liefern ein long in der entsprechenden Einheit. Zudem gibt es eine Methode convert(…), die von einer Einheit in einer andere umrechnet.
[zB]Beispiel
Konvertiere 23.746.387 Millisekunden in Stunden:
System.out.println( TimeUnit.HOURS.convert(
23746387, TimeUnit.MILLISECONDS ) ); // 6
extends Enum<TimeUnit>
implements Serializable, Comparable<TimeUnit>
NANOSECONDS, MICROSECONDS, MILLISECONDS, SECONDS, MINUTES, HOURS, DAYS
Aufzählungselemente von TimeUnitlong toDays(long duration)
long toHours(long duration)
long toMicros(long duration)
long toMillis(long duration)
long toMinutes(long duration)
long toNanos(long duration)
long toSeconds(long duration)
long convert(long sourceDuration, TimeUnit sourceUnit)
Liefert sourceUnit.toXXX(sourceDuration), wobei XXX für die jeweilige Einheit steht. Beispielsweise liefert es HOURS.convert(sourceDuration, sourceUnit), dann sourceUnit.toHours(1). Die Lesbarkeit der Methode ist nicht optimal, daher sollten die anderen Methoden bevorzugt werden.