Advanced Java Services | java.time API |
Die neue API ist das Ergebnis der Entwicklung von JSR 310. Federführend in diesem Projekt ist Stephen Colebourne, der auch der Entwickler von Joda Time ist.
Die Entwicklung von JSR 310 reicht zurück bis ins Jahre 2009. Stephen Colebourne erklärte in seinem Blog 2010 das Konzept von JSR 310 (what-about-jsr-310_153). JSR 310 ist kein direkter Nachfolger von Joda Time, übernimmt aber wesentliche Konzepte daraus. In seinem Blog erklärt Why JSR-310 isn't Joda-Time die Schwachpunkte (design flaws) von Joda Time.
Die neue Time-API wird allgemein als deutlicher Fortschritt gegenüber den Klassen java.util.Date und java.util.Calendar anerkannt. Jedoch gibt es auch Kritik an dem neuen Konzept, eine Stimme hier ist Meno Hochschild , der in seinem Blog kritisch Stellung zu JSR310 nimmt.
In diesem Package liegen 15 Klassen, 2 Enums und eine Exception.
In diesem Package liegen 6 Interfaces, 11 Klassen und 4 Enums
Im Package java.time.format liegen 3 Klassen, 4 Enums und eine Excedption
Im Package java.time.temporal liegen 7 Interfaces, 6 Klassen, 2 Enums und eine Exception
Im Package java.time.zone liegen 4 Klassen, eine Enum und eine Exception
Hier zunächst die ausführlichen Diagramme. Die Hierarchie ist recht umfangreich und auch hier nicht vollständig dargestellt.
Wegen der (zwangsläufigen) Unübersichtlichkeit der ausführlichen Fassung hier eine Kurzfassung, die hoffentlich das Wesentliche zusammenfaßt und einprägsamer ist. Viele Methoden arbeiten nämlich mit den Dach-Interfaces als Parameter.
Dasselbe gilt für die folgenden Kurzfassungen.
Ein TemporalAmount ist also eine Duration oder eine Period. Ein TemporalField ist immer ein ChronoField. Eine TemporalUnit ist immer eine ChronoUnit.
Abgeleitet von der Erdrotation ist ein Tag die Dauer einer vollständigen Drehung um die eigene Achse. Dieser Tag wird bekanntlich eingeteilt in Stunden, Minuten und Sekunden, sodaß ein Tag aus 24 x 60 x 60 = 86400 Sekunden besteht. Da die Erdrotation aber Schwankungen unterliegt gibt es kleine Absweichungen, die der gregorianische Kalender trotz der verfeinerten Schaltjahresregel nicht berücksichtigten kann (auch andere Kalendersysteme sind dazu nicht in der Lage). Seit der Einführung von Atomuhren im Jahre 1967 gleicht man die Unregelmäßigkeiten der Erdrotation durch das Einschieben von Schaltsekunden (leapseconds) aus um zu verhindern, daß sich diese zu größeren Zeiträumen aufaddieren. Interessanterweise wirken sich die Unregelmäßigen bei der Rotation um die Erdachse nur so aus, daß man Schaltsekunden hinzufügen muß, das heißt, die Tage werden minimal länger, da sich die Rotationsgeschwindigkeit der Erde minimal verlangsamt. Der umgekehrte Fall, daß die Rotationsgeschwindikeit zunimmt und dadurch die Tage kürzer werden ist seit man so genau messen kann noch nie aufgetreten. Über das Internet stellen Rechner ihre Zeit nach einer Atomuhr und dehnen falls notwendig einen Sekunde um einen Sekundenbruchteil, sodaß ein Tag immer 86400 Sekunden lang ist. Die neue java.time API übernimmt im wesentlichen dieses Konzept.
Die ISO-8601 (wikipedia) Norm etabliert einen internationalen Standard für Zeitangaben und Formate. Das wichtigste Format ist UTC (wikipedia), die Coordinated Universal Time. Der genaue Aufbau kann den Seiten auf Wikipedia entnommen werden. Die java.time API unterstützt UTC, aber nicht die anderen Formate. Hier einige Beispiele für Formate.
Date and time ISO 8601 | |
---|---|
Date: | 2014-05-26 |
Combined date and time in UTC: | 2014-05-26T16:46:09+00:00 |
Combined date and time in UTC: | 2014-05-26T16:46:09Z |
Week: | 2014-W22 |
Date with week number: | 2014-W22-1 |
Ordinal date: | 2014-146 |
java.time. unterstützt die UTC-Formate in roter Farbe.
Diese Zeitachse ist quasi-kulturneutral. Allerdings wird der Nullpunkt der Zeitachse auf den 1. Januar 1970 (Mitternacht 0 Uhr) gelegt bezogen auf den Meridian des Greenwich Royal Observatory in London. Dieser Zeitpunkt, der Epoch genannt wird ist auch der Nullpunkt der von UNIX verwendeten Zeitachse (siehe auch Unix time auf wikipedia). Von diesem Zeitpunkt aus werden Sekunden vorwärts und rückwarts gezählt. In Java kann man von diesem Zeitpunkt eine Billion Jahre zurück und eine Billion Jahre vorwärts zählen, dies sollte wirklich alle Bedürfnisse der Praxis abdecken.
Die GMT ist ist eine Zeit ohne Zeitzone und ohne Offset, es gibt also weder Sommerzeit noch Winterzeit noch eine Zeitzone. In Jave wird diese Zeit im wesentlichen durch die Klasse Instant modelliert. GMT ist die ältere Bezeichnung, die mittlerweile von UTC abgelöst worden ist, aber noch häufig verwendet wird.
Zur Verdeutlichung sind die Methoden, die alle vier Klassen gemeinsam haben blau eingefärbt.
Die Struktur der DateTime-Klassen und Instant | |||||
---|---|---|---|---|---|
Methodenname | Verhalten | Instant | LocalDateTime | OffsetDateTime | ZonedDateTime |
atXxx | Transfer-Methoden, die einen anderen Zeittyp liefern | x | x | x | |
format(DateTimeFormatter formatter) | Formats this date-time using the specified formatter. | x | x | x | |
from(TemporalAccessor temporal) | statische Factorymethode die eine Instanz aus einem TemporalAccessor erstellt. (Ein TemporalAccessor ist eine Date/Time Klasse) | x | x | x | |
getXxx | Methoden, die entweder einen Teil der Zeitangabe liefern, etwa nur die Millisekunden oder etwa auch die gesmate Zeitangabe in Sekunden umrechnen | x | x | x | x |
isAfter, isBefore | klassische is-Methoden die zwei Zeitangaben vergleichen | x | x | x | x |
minus | Methoden, die eine Zeitdauer zu einer Zeit addieren und als neue Zeit zurückgeben | x | x | x | x |
now | statische Factorymethoden, die die aktuelle Zeit liefern | x | x | x | x |
of | statische Factorymethoden, die die Zeit aus den übergebenen Argumenten liefern | x | x | x | x |
parse | statische Factorymethoden, die die Zeit aus dem übergebenen String liefern | x | x | x | x |
plus | Methoden, die eine Zeitdauer zu einer Zeit addieren und als neue Zeit zurückgeben | x | x | x | x |
toXxx | Methoden, die die Instanz zu einem String, zu einer Zahl oder zu einem anderen Date/Time-Typ umwandeln. | x | x | x | x |
truncatedTo(TemporalUnit unit) | Returns a copy of this DateTimeObject truncated to the specified unit. A TemporalUnit is a ChronoUnit. | x | x | x | x |
until(Temporal endExclusive, TemporalUnit unit) | Calculates the amount of time until another date-time in terms of the specified unit. Ein Temporal ist eine Date/Time Klasse, eine TemporalUnit ist eine ChronoUnit. |
x | x | x | x |
withXxx | Erstellt mit Hilfe der übergebenen Paramter eine neue Instanz desselben Typs. | x | x | x | x |
Methodenname | Verhalten | Instant | LocalDateTime | OffsetDateTime | ZonedDateTime |
Die Enumklasse ChronoUnit ist die einzige Implementierun des Interfaces TemporalUnit und wird u.a. von den Methoden von Duration und Period verwendet. Die Konstanten sind hier der Größe nach sortiert und nicht wie in der API alphabetisch.
Enum Konstante | Beschreibung |
---|---|
NANOS | Unit that represents the concept of a nanosecond, the smallest supported unit of time. |
MICROS | Unit that represents the concept of a microsecond. |
MILLIS | Unit that represents the concept of a millisecond. |
SECONDS | Unit that represents the concept of a second. |
MINUTES | Unit that represents the concept of a minute. |
HOURS | Unit that represents the concept of an hour. |
HALF_DAYS | Unit that represents the concept of half a day, as used in AM/PM. |
DAYS | Unit that represents the concept of a day. |
WEEKS | Unit that represents the concept of a week. |
MONTHS | Unit that represents the concept of a month. |
YEARS | Unit that represents the concept of a year. |
DECADES | Unit that represents the concept of a decade. |
CENTURIES | Unit that represents the concept of a century. |
MILLENNIA | Unit that represents the concept of a millennium. |
ERAS | Unit that represents the concept of an era. |
FOREVER | Artificial unit that represents the concept of forever. |