Rheinwerk Computing < openbook > Rheinwerk Computing - Professionelle Bücher. Auch für Einsteiger.
Professionelle Bücher. Auch für Einsteiger.
 
Inhaltsverzeichnis
Vorwort
1 Java ist auch eine Sprache
2 Imperative Sprachkonzepte
3 Klassen und Objekte
4 Der Umgang mit Zeichenketten
5 Eigene Klassen schreiben
6 Objektorientierte Beziehungsfragen
7 Ausnahmen müssen sein
8 Äußere.innere Klassen
9 Besondere Typen der Java SE
10 Generics<T>
11 Lambda-Ausdrücke und funktionale Programmierung
12 Architektur, Design und angewandte Objektorientierung
13 Die Klassenbibliothek
14 Einführung in die nebenläufige Programmierung
15 Einführung in Datenstrukturen und Algorithmen
16 Einführung in grafische Oberflächen
17 Einführung in Dateien und Datenströme
18 Einführung ins Datenbankmanagement mit JDBC
19 Einführung in <XML>
20 Testen mit JUnit
21 Bits und Bytes und Mathematisches
22 Die Werkzeuge des JDK
A Java SE Paketübersicht
Stichwortverzeichnis

Download:
- Beispielprogramme, ca. 20,0 MB
- Übungsaufgaben, ca. 1,8 MB
- Musterlösungen, ca. 0,8 MB

Buch bestellen
Ihre Meinung?

Spacer
<< zurück
Java ist auch eine Insel von Christian Ullenbloom
Das umfassende Handbuch
Buch: Java ist auch eine Insel

Java ist auch eine Insel
Rheinwerk Computing
1306 Seiten, gebunden, 11. Auflage
49,90 Euro, ISBN 978-3-8362-2873-2
Pfeil 13 Die Klassenbibliothek
Pfeil 13.1 Die Java-Klassenphilosophie
Pfeil 13.1.1 Übersicht über die Pakete der Standardbibliothek
Pfeil 13.1.2 Compact-Profile
Pfeil 13.2 Sprachen der Länder
Pfeil 13.2.1 Sprachen und Regionen über Locale-Objekte
Pfeil 13.3 Die Klasse Date
Pfeil 13.3.1 Objekte erzeugen und Methoden nutzen
Pfeil 13.3.2 Date-Objekte sind nicht immutable
Pfeil 13.4 Calendar und GregorianCalendar
Pfeil 13.4.1 Die abstrakte Klasse Calendar
Pfeil 13.4.2 Calendar nach Date und Millisekunden fragen
Pfeil 13.4.3 Abfragen und Setzen von Datumselementen über Feldbezeichner
Pfeil 13.4.4 Kalender-Exemplare bauen über den Calendar.Builder
Pfeil 13.4.5 Der gregorianische Kalender
Pfeil 13.4.6 Date-Time-API in Java 8
Pfeil 13.5 Klassenlader (Class Loader) und Klassenpfad
Pfeil 13.5.1 Woher die kleinen Klassen kommen
Pfeil 13.5.2 Setzen des Klassenpfades
Pfeil 13.5.3 Die wichtigsten drei Typen von Klassenladern
Pfeil 13.6 Die Utility-Klasse System und Properties
Pfeil 13.6.1 Systemeigenschaften der Java-Umgebung
Pfeil 13.6.2 line.separator
Pfeil 13.6.3 Eigene Properties von der Konsole aus setzen *
Pfeil 13.6.4 Umgebungsvariablen des Betriebssystems *
Pfeil 13.6.5 Einfache Zeitmessung und Profiling *
Pfeil 13.7 Einfache Benutzereingaben
Pfeil 13.7.1 Grafischer Eingabedialog über JOptionPane
Pfeil 13.7.2 Geschützte Passwort-Eingaben mit der Klasse Console *
Pfeil 13.8 Ausführen externer Programme *
Pfeil 13.8.1 ProcessBuilder und Prozesskontrolle mit Process
Pfeil 13.8.2 Einen Browser, E-Mail-Client oder Editor aufrufen
Pfeil 13.9 Benutzereinstellungen *
Pfeil 13.9.1 Benutzereinstellungen mit der Preferences-API
Pfeil 13.9.2 Einträge einfügen, auslesen und löschen
Pfeil 13.9.3 Auslesen der Daten und Schreiben in einem anderen Format
Pfeil 13.9.4 Auf Ereignisse horchen
Pfeil 13.9.5 Zugriff auf die gesamte Windows-Registry
Pfeil 13.10 Zum Weiterlesen
 
Zum Seitenanfang

13.4Calendar und GregorianCalendar Zur vorigen ÜberschriftZur nächsten Überschrift

Ein Kalender unterteilt die Zeit in Einheiten wie Jahr, Monat, Tag. Der bekannteste Kalender ist der gregorianische Kalender, den Papst Gregor XIII. im Jahre 1582 einführte. Vor seiner Einführung war der julianische Kalender populär, der auf Julius Cäsar zurückging – daher auch der Name. Er stammt aus dem Jahr 45 vor unserer Zeitrechnung. Der gregorianische und der julianische Kalender sind Sonnenkalender, die den Lauf der Erde um die Sonne als Basis für die Zeiteinteilung nutzen; der Mond spielt keine Rolle. Daneben gibt es Mondkalender wie den islamischen Kalender und die Lunisolarkalender, die Sonne und Mond miteinander verbinden. Zu diesem Typus gehören der chinesische, der griechische und der jüdische Kalender.

Mit Exemplaren vom Typ Calendar ist es möglich, Datum und Uhrzeit in den einzelnen Komponenten wie Jahr, Monat, Tag, Stunde, Minute, Sekunde zu setzen und zu erfragen. Da es unterschiedliche Kalendertypen gibt, ist Calendar eine abstrakte Basisklasse, und Unterklassen bestimmen, wie konkret eine Abfrage oder Veränderung für ein bestimmtes Kalendersystem aussehen muss. Bisher bringt die Java-Bibliothek mit der Unterklasse GregorianCalendar nur eine öffentliche konkrete Implementierung mit, deren Exemplare Daten und Zeitpunkte gemäß dem gregorianischen Kalender verkörpern. Intern gibt es weiterhin eine Klasse für einen japanischen und buddhistischen Kalender; sie werden immer verwendet, wenn die Locale ja_JP_JP bzw. th_TH ist.[ 216 ] IBM hat mit International Components for Unicode for Java (ICU4J) unter http://icu.sourceforge.net/ weitere Klassen wie ChineseCalendar, BuddhistCalendar, JapaneseCalendar, HebrewCalendar und IslamicCalendar freigegeben. Hier findet sich auch einiges zum Thema Ostertage.

 
Zum Seitenanfang

13.4.1Die abstrakte Klasse Calendar Zur vorigen ÜberschriftZur nächsten Überschrift

Die Klasse Calendar besitzt zum einen Anfrage- und Modifikationsmethoden für konkrete Exemplare und zum anderen statische Fabrikmethoden. Eine einfache statische Methode ist getInstance(), um ein konkretes Objekt zu bekommen.

abstract class java.util.Calendar
implements Serializable, Cloneable, Comparable<Calendar>

  • static Calendar getInstance()
    Liefert einen Standard-Calendar mit der Standard-Zeitzone und Standard-Lokalisierung zurück.

Neben der parameterlosen Variante von getInstance() gibt es drei weitere Varianten, denen ein TimeZone-Objekt und Locale-Objekt mit übergeben werden kann. Damit kann dann der Kalender auf eine spezielle Zeitzone und einen Landstrich zugeschnitten werden.

[+]Hinweis

Anders als Date hat Calendar (bzw. GregorianCalendar) keine menschenfreundliche toString()-Methode. Der String ist eher eine Debug-Meldung und listet alle Zustände des Objekts auf:

java.util.GregorianCalendar[time=1187732409256,areFieldsSet=true,areAllFieldsSet=true, …

Insgesamt gibt es drei Varianten, um an ein konkretes Calendar-Exemplar zu kommen:

  • Aufruf einer Fabrikmethode Calendar.getInstance(…)

  • Calendar.Builder nutzen, was das Builder-Pattern realisiert

  • eine Unterklasse von Calendar nutzen, etwa GregorianCalendar

 
Zum Seitenanfang

13.4.2Calendar nach Date und Millisekunden fragen Zur vorigen ÜberschriftZur nächsten Überschrift

Um von einem Calendar die Anzahl der vergangenen Millisekunden seit dem 1.1.1970 abzufragen, dient getTimeInMillis() (eine ähnliche Methode hat auch Date, nur heißt sie dort getTime()).

[+]Hinweis

Calendar und Date haben beide eine getTime()-Methode. Nur liefert die Calendar-Methode getTime() ein java.util.Date-Objekt und die Date-Methode getTime() ein long. Gutes API-Design sieht anders aus. Damit Entwickler aber keine unschönen cal.getTime().getTime()-Ausdrücke schreiben müssen, um vom Calendar die Anzahl der Millisekunden zu beziehen, ist getTimeInMillis() im Angebot.

abstract class java.util.Calendar
implements Serializable, Cloneable, Comparable<Calendar>

  • final long getTimeInMillis()
    Liefert die seit der Epoche (January 1, 1970 00:00:00.000 GMT, Gregorian) vergangene Zeit in Millisekunden.

  • final Date getTime()
    Liefert ein Date-Objekt zu diesem Calendar.

[zB]Beispiel

Bestimme die Anzahl der Tage, die seit einem bestimmten Tag, Monat und Jahr vergangen sind:

int date = 1;
int month = Calendar.JANUARY;
int year = 1900;
long ms = new GregorianCalendar( year, month, date ).getTimeInMillis();
long days = TimeUnit.MILLISECONDS.toDays( System.currentTimeMillis() – ms );
System.out.println( days ); // 40303

Zum Aufbau eines Calendar-Objektes nutzt das Beispiel den parametrisieren Konstruktor von GregorianCalendar.

 
Zum Seitenanfang

13.4.3Abfragen und Setzen von Datumselementen über Feldbezeichner Zur vorigen ÜberschriftZur nächsten Überschrift

Das Abfragen und Setzen von Datumselementen eines Kalenders erfolgt mit den überladenen Methoden get(…) und set(…). Beide erwarten als erstes Argument einen Feldbezeichner – eine Konstante aus der Klasse Calendar –, der angibt, auf welches Datum-/Zeitfeld zugegriffen werden soll. Die get(…)-Methode liefert den Inhalt des angegebenen Felds, und set(…) schreibt den als zweites Argument übergebenen Wert in das Feld.

[zB]Beispiel

Führe Anweisungen aus, wenn es 19 Uhr ist:

if ( Calendar.getInstance().get( Calendar.HOUR_OF_DAY ) == 19 )
...

Die folgende Tabelle gibt eine Übersicht der Feldbezeichner und ihrer Wertebereiche im Fall des konkreten GregorianCalendar.

abstract class java.util.Calendar
implements Serializable, Cloneable, Comparable<Calendar>

Feldbezeichner
Calendar.*

Minimalwert

Maximalwert

Erklärung

ERA

0 (BC)

1 (AD)

Datum vor oder nach Christus

YEAR

1

theoretisch unbeschränkt

Jahr

MONTH

0

11

Monat (nicht von 1 bis 12!)

DAY_OF_MONTH
alternativ DATE

1

31

Tag

WEEK_OF_YEAR

1

54

Woche

WEEK_OF_MONTH

1

6

Woche des Monats

DAY_OF_YEAR

1

366

Tag des Jahres

DAY_OF_WEEK

1

7

Tag der Woche
(1 = Sonntag, 7 = Samstag)

DAY_OF_WEEK_IN_MONTH

1

6

Tag der Woche im Monat

HOUR

0

11

Stunde von 12

HOUR_OF_DAY

0

23

Stunde von 24

MINUTE

0

59

Minute

SECOND

0

59

Sekunden

MILLISECOND

0

999

Millisekunden

AM_PM

0

1

vor 12, nach 12

ZONE_OFFSET

13 × 60 × 60 × 1000

+14 × 60 × 60 × 1000

Zeitzonenabweichung in Millisekunden

DST_OFFSET

0

2 × 60 × 60 × 1000

Sommerzeitabweichung in Millisekunden

Tabelle 13.3Konstanten aus der Klasse Calendar

Beachtenswert sind der Anfang der Monate mit 0 und der Anfang der Wochentage mit 1 (SUNDAY), 2 (MONDAY), ..., 7 (SATURDAY) – Konstanten der Klasse Calendar stehen in Klammern. Die Woche beginnt in der Java-Welt also bei 1 und Sonntag, statt – wie vielleicht anzunehmen – bei 0 und Montag.

[zB]Beispiel

Ist ein Date-Objekt gegeben, so speichert es Datum und Zeit. Soll der Zeitanteil gelöscht werden, so bietet Java dafür keine eigene Methode. Die Lösung ist, Stunden, Minuten, Sekunden und Millisekunden von Hand auf 0 zu setzen. Löschen wir vom Hier und Jetzt die Zeit:

Date date = new Date();
Calendar cal = Calendar.getInstance();
cal.setTime( date );
cal.set( Calendar.HOUR_OF_DAY, 0 );
cal.set( Calendar.MINUTE, 0 );
cal.set( Calendar.SECOND, 0 );
cal.set( Calendar.MILLISECOND, 0 );
date = cal.getTime();

Eine Alternative wäre, den Konstruktor GregorianCalendar(int year, int month, int dayOfMonth) mit den Werten vom Datum zu nutzen.

abstract class java.util.Calendar
implements Serializable, Cloneable, Comparable<Calendar>

  • int get(int field)
    Liefert den Wert für field.

  • void set(int field, int value)
    Setzt das Feld field mit dem Wert value.

  • final void set(int year, int month, int date)
    Setzt die Werte für Jahr, Monat und Tag.

  • final void set(int year, int month, int date, int hourOfDay, int minute)
    Setzt die Werte für Jahr, Monat, Tag, Stunde und Minute.

  • final void set(int year, int month, int date, int hourOfDay, int minute, int second)
    Setzt die Werte für Jahr, Monat, Tag, Stunde, Minute und Sekunde.

[+]Hinweis

Wo die Date-Klasse etwa spezielle (veraltete) Methoden wie getYear(), getDay(), getHours() anbietet, so müssen Nutzer der Calendar-Klasse immer die get(int field)-Methode nutzen. Es gibt kaum Getter für den Zugriff auf ein bestimmtes Feld.

Werte relativ setzen

Neben der Möglichkeit, die Werte entweder über den Konstruktor oder über set(…) absolut zu setzen, sind auch relative Veränderungen möglich. Dazu wird die add(…)-Methode eingesetzt, die wie set(…) als erstes Argument einen Feldbezeichner bekommt und als zweites die Verschiebung.

[zB]Beispiel

Was ist der erste und letzte Tag einer Kalenderwoche?

Calendar cal = Calendar.getInstance();
cal.set( Calendar.YEAR, 2014 );
cal.set( Calendar.WEEK_OF_YEAR, 15 );
cal.set( Calendar.DAY_OF_WEEK, Calendar.MONDAY );
System.out.printf( "%tD ", cal ); // 04/07/14
cal.add( Calendar.DAY_OF_WEEK, 6 );
System.out.printf( "%tD", cal ); // 04/13/14

Die Methode add(…) setzt das Datum um sechs Tage hoch.

Da es keine sub(…)-Methode gibt, können die Werte bei add(…) auch negativ sein.

[zB]Beispiel

Wo waren wir heute vor einem Jahr?

Calendar cal = Calendar.getInstance();
System.out.printf( "%tF%n", cal ); // 2013-02-01
cal.add( Calendar.YEAR, -1 );
System.out.printf( "%tF%n", cal ); // 2012-02-01

Eine weitere Methode roll(…) ändert keine folgenden Felder, was add(…) macht, wenn etwa zum Dreißigsten eines Monats zehn Tage addiert werden.

abstract class java.util.Calendar
implements Serializable, Cloneable, Comparable<Calendar>

  • abstract void add(int field, int amount)
    Addiert (bzw. subtrahiert, wenn amount negativ ist) den angegeben Wert auf dem (bzw. vom) Feld.

  • abstract void roll(int field, boolean up)
    Setzt eine Einheit auf dem gegebenen Feld hoch oder runter, ohne die nachfolgenden Felder zu beeinflussen. Ist der aktuelle Feldwert das Maximum (bzw. Minimum) und wird um eine Einheit addiert (bzw. subtrahiert), ist der nächste Feldwert das Minimum (bzw. Maximum).

  • void roll(int field, int amount)
    Ist amount positiv, führt diese Methode die Operation roll(field, true) genau amount-mal aus, ist amount negativ, dann wird amount-mal roll(field, false) aufgerufen.

 
Zum Seitenanfang

13.4.4Kalender-Exemplare bauen über den Calendar.Builder Zur vorigen ÜberschriftZur nächsten Überschrift

Java 8 führte in Calendar die neue statische innere Klasse Builder ein, mit der sich leicht Calendar-Exemplare mit gesetzten Feldern aufbauen lassen. Die allgemeine Schreibweise ist wie folgt:

Calendar cal = new Calendar.Builder()
.setXXX( … ).setXXX( … ).setXXX( … )
.build();

Zum Setzen von Feldern gibt es setXXX(…)-Methoden, am Ende folgt ein Aufruf von build(), der ein fertiges Calendar-Objekt liefert.

static class java.util.Calendar.Builder

  • Calendar.Builder setDate(int year, int month, int dayOfMonth)

  • Calendar.Builder set(int field, int value)

  • Calendar.Builder setFields(int... fieldValuePairs)

  • Calendar.Builder setInstant(Date instant)

  • Calendar.Builder setInstant(long instant)

  • Calendar.Builder setTimeOfDay(int hourOfDay, int minute, int second)

  • Calendar.Builder setTimeOfDay(int hourOfDay, int minute, int second, int millis)

  • Calendar.Builder setWeekDate(int weekYear, int weekOfYear, int dayOfWeek)

  • Calendar.Builder setTimeZone(TimeZone zone)

Etwas weniger gebräuchliche Methoden sind weiterhin setCalendarType(String type) – was Rückgaben von Calendar.getAvailableCalendarTypes() erlaubt und alternativ zu »gregory« auch »gregorian« bzw. »iso8601« –, setLenient(boolean lenient), setLocale(Locale locale) und setWeekDefinition(int firstDayOfWeek, int minimalDaysInFirstWeek).

 
Zum Seitenanfang

13.4.5Der gregorianische Kalender Zur vorigen ÜberschriftZur nächsten Überschrift

Die Klasse GregorianCalendar erweitert die abstrakte Klasse Calendar. Sieben Konstruktoren stehen zur Verfügung; vier davon sehen wir uns an.

class java.util.GregorianCalendar
extends Calendar

  • GregorianCalendar()
    Erzeugt ein standardmäßiges GregorianCalendar-Objekt mit der aktuellen Zeit in der voreingestellten Zeitzone und Lokalisierung.

  • GregorianCalendar(int year, int month, int date)
    Erzeugt ein GregorianCalendar-Objekt in der voreingestellten Zeitzone und Lokalisierung. Jahr, Monat (der zwischen 0 und 11 und nicht zwischen 1 und 12 liegt) und Tag legen das Datum fest.

  • GregorianCalendar(int year, int month, int date, int hour, int minute)
    Erzeugt ein GregorianCalendar-Objekt in der voreingestellten Zeitzone und Lokalisierung. Das Datum legen Jahr, Monat (0 <= month <= 11 ), Tag, Stunde und Minute fest.

  • GregorianCalendar(int year, int month, int date, int hour, int minute, int second)
    Erzeugt ein GregorianCalendar-Objekt in der voreingestellten Zeitzone und Lokalisierung. Das Datum legen Jahr, Monat (0 <= month <= 11), Tag, Stunde, Minute und Sekunde fest.

[+]Hinweis

Die Monate beginnen bei 0, sodass new GregorianCalendar(1973, 3, 12) nicht den 12. März, sondern den 12. April ergibt! Damit Anfrageprobleme vermieden werden, sollten die Calendar-Konstanten JANUARY (0), FEBRUARY, MARCH, APRIL, MAY, JUNE, JULY, AUGUST, SEPTEMBER, OCTOBER, NOVEMBER, DECEMBER (11) verwendet werden. Die spezielle Variable UNDECIMBER (12) steht für den dreizehnten Monat, der etwa bei einem Mondkalender anzutreffen ist. Die Konstanten sind keine typsicheren Aufzählungen, bieten aber den Vorteil, als int einfach mit ihnen zählen zu können.

Neben den hier aufgeführten Konstruktoren gibt es noch weitere, die es erlauben, die Zeitzone und Lokalisierung zu ändern. Standardmäßig eingestellt sind die lokale Zeitzone und die aktuelle Lokalisierung. Ist eines der Argumente im falschen Bereich, löst der Konstruktor eine IllegalArgumentException aus.

[+]Hinweis

Zum Aufbau von Calendar-Objekten gibt es nun zwei Möglichkeiten:

Calendar c = Calendar.getInstance();

und

Calendar c = new GregorianCalendar();

Die erste Variante ist besonders in internationalisierter Software zu bevorzugen, da es einige Länder gibt, die nicht nach dem gregorianischen Kalender arbeiten.

Calendar c = Calendar.getInstance( new Locale("ja", "JP", "JP") );
 
Zum Seitenanfang

13.4.6Date-Time-API in Java 8 Zur vorigen ÜberschriftZur nächsten Überschrift

Seit Java 8 gibt es ein neues Paket java.time, das alle bisherigen Java-Typen rund um Datum- und Zeitverarbeitung überflüssig macht. Mit anderen Worten: Mit den neuen Typen lassen sich Date, Calendar, GregorianCalendar, TimeZone usw. streichen und ersetzen. Natürlich gibt es Adapter zwischen den APIs, doch gibt es nur noch sehr wenige zwingende Gründe, heute bei neuen Programmen auf die älteren Typen zurückzugreifen – ein Grund ist natürlich die heilige Kompatibilität.

Die neue API basiert auf dem standardisierten Kalendersystem von ISO-8601, und das deckt ab, wie ein Datum, wie Zeit, Datum und Zeit, UTC, Zeitintervalle (Dauer/Zeitspanne) und Zeitzonen repräsentiert werden. Die Implementierung basiert auf dem Gregorianischen Kalender, wobei auch andere Kalendertypen denkbar sind. Javas Kalendersystem greift auf andere Standards bzw. Implementierungen zurück, unter anderem auf das Unicode Common Locale Data Repository (CLDR) zur Lokalisierung von Wochentagen oder die Time-Zone Database (TZDB), die alle Zeitzonenwechsel seit 1970 dokumentiert. In Java nutzen die XML-APIs schon länger ISO-8601-Kalender, denn Schema-Dateien nutzen einen XMLGregorianCalendar, und selbst für Dauern gibt einen eigenen Typ Duration.

Geschichte

Über die alten Datumsklassen meckert die Java-Community seit über zehn Jahren; nicht ganz zu Unrecht, da ein Date zum Beispiel ein Date-Time ist, Kalender fehlen, die Sommerzeitumstellung verschiedener Länder nicht korrekt behandelt wird und wegen weiterer Schwächen.[ 217 ] Daher geht die Entwicklung der Date-Time-API lange zurück und basiert auf Ideen von Joda-Time (http://joda-time.sourceforge.net/), einer populären quelloffenen Bibliothek. Spezifiziert im JSR-310 (eingereicht am 30. Jan 2007)[ 218 ] und angedacht für Java 7 (was vier Jahre später, im Juli 2011 kam) wurde die API erst in Java 8 Teil der Java SE. Für Java 1.7 gibt es einen Back-Port (https://github.com/ThreeTen/threetenbp), um später leicht die Codebasis auf Java 8 zu migrieren, der durchaus interessant ist.

Erster Überblick

Die zentralen temporalen Typen aus der Date-Time-API sind schnell dokumentiert:

Typ

Beschreibung

Feld(er)

LocalDate

Repräsentiert ein übliches Datum.

Jahr, Monat, Tag

LocalTime

Repräsentiert eine übliche Zeit.

Stunden, Minuten, Sekunden, Nanosek.

LocalDateTime

Kombination aus Datum und Zeit

Jahr, Monat, Tag, Stunden, Minuten, Sekunden, Nanosek.

Period

Dauer zwischen zwei LocalDates

Jahr, Monat, Tag

Year

nur Jahr

Jahr

Month

nur Monat

Monat

MonthDay

nur Monat und Tag

Monat, Tag

OffsetTime

Zeit mit Zeitzone

Stunden, Minuten, Sekunden, Nanosek., Zonen-Offset

OffsetDateTime

Datum und Zeit mit Zeitzone als UTC-Offset

Jahr, Monat, Tag, Stunden, Minuten, Sekunden, Nanosek., Zonen-Offset

ZonedDateTime

Datum und Zeit mit Zeitzone als ID und Offset

Jahr, Monat, Tag, Stunden, Minuten, Sekunden, Nanosek., Zonen-Info

Instant

fortlaufende Maschinenzeit

Nanosekunden

Duration

Zeitintervall zwischen zwei Instants

Sekunden/Nanosek.

Tabelle 13.4Alle temporalen Klassen aus java.timeMenschenzeit und Maschinenzeit

Datum und Zeit, die wir als Menschen in Einheiten wie Tagen und Minuten verstehen, nennen wir Menschenzeit (engl. human time), die fortlaufende Zeit des Computers, die eine Auflösung im Nanosekundenbereich hat, Maschinenzeit. Die Maschinenzeit startet dabei von einer Zeit, die wir Epoche nennen. Aus Tabelle 13.4 lässt sich gut ablesen, dass die meisten Klassen für uns Menschen gemacht sind, und sich nur Instant/Duration auf die Maschinenzeit bezieht. LocalDate, LocalTime und LocalDateTime repräsentieren Menschenzeit ohne Bezug zu einer Zeitzone, ZonedDateTime mit Zeitzone. Bei der Auswahl der richtigen Zeitklassen für eine Aufgabenstellung ist das natürlich die erste Überlegung, ob die Menschenzeit oder die Maschinenzeit repräsentiert werden soll, dann was genau für Felder nötig sind und ob eine Zeitzone relevant ist oder nicht. Soll zum Beispiel die Ausführungszeit gemessen werden, ist es unnötig, zu wissen, an welchem Datum die Messung begann und endet, hier ist Duration korrekt, nicht Period.

[zB]Beispiel

LocalDate now = LocalDate.now();
System.out.println( now ); // 2014-01-30
System.out.printf( "%d. %s %d", now.getDayOfMonth(), now.getMonth(), now.getYear() ); // 30. JANUARY 2014
LocalDate bdayMLKing = LocalDate.of( 1929, Month.JANUARY, 15 );
DateTimeFormatter formatter = DateTimeFormatter.ofPattern( "d. MMMM yyyy" );
System.out.println( formatter.format( bdayMLKing ) ); // 15. Januar 1929

Alle Klassen basieren standardmäßig auf dem ISO-System, andere Kalendersysteme, wie der Japanische Kalender, werden über Typen aus java.time.chrono erzeugt, natürlich sind auch ganz neue Systeme möglich.

[zB]Beispiel

ChronoLocalDate now = JapaneseChronology.INSTANCE.dateNow();
System.out.println( now ); // Japanese Heisei 26-01-30

Paketübersicht

Die Typen der Date-Time-API verteilen sich auf verschiedene Pakete:

  • java.time: Enthält die Standardklassen wie LocalTime, Instant usw. Alle Typen basieren auf dem Kalendersystem ISO-8601, das landläufig unter Gregorianischer Kalender bekannt ist. Der wird erweitert zum sogenannten Proleptic Gregorian Kalender, das ist ein Gregorianischer Kalender, der auch für die Zeit vor 1582 (der Einführung des Kalenders) gültig ist, damit eine konsistente Zeitlinie entsteht.

  • java.time.chrono: Hier befinden sich vorgefertigte alternative (also Nicht-ISO-) Kalendersysteme, wie Japanischer Kalender, Thai-Buddhist-Kalender, Islamischer Kalender (genannt Hijrah) und ein paar weitere.

  • java.time.format: Klassen zum Formatieren und Parsen von Datum- und Zeit, wie der genannte DateTimeFormatter

  • java.time.zone: Unterstützende Klassen für Zeitzonen, etwa ZonedDateTime

  • java.time.temporal: Tiefer liegende API, die Zugriff und Modifikation einzelner Felder eines Datums/Zeitwerts erlaubt

Design-Prinzipen

Bevor wir uns mit den einzelnen Klassen auseinandersetzen, wollen wir uns mit den Design-Prinzipien beschäftigen, denn alle Typen der Date-Time-API folgen wiederkehrenden Mustern. Die erste und wichtigste Eigenschaft ist, dass alle Objekte immutable sind, also nicht veränderbar. Das ist bei der »alten« API anders, Date und die Calendar-Klassen sind veränderbar, mit teils verheerenden Folgen; denn werden diese Objekte rumgereicht und verändert, kann es zu unkalkulierbaren Seiteneffekten kommen. Die Klassen der neuen Date-Time-API sind immutable, und so stehen die Datums-/Zeit-Klassen wie LocalTime oder Instant den veränderbaren Typen wie Date oder Calendar gegenüber. Alle Methoden, die nach Änderung aussehen, erzeugen neue Objekte mit den gewünschten Änderungen. Seiteneffekte bleiben also aus, und alle Typen sind threadsicher.

Unveränderbarkeit ist eine Designeigenschaft wie auch die Tatsache, dass null nicht als Argument erlaubt wird. In der Java-API wird oftmals null akzeptiert, weil es etwas Optionales ausdrückt, doch die Date-Time-API straft dies in der Regel mit einer NullPointerExcpetion. Dass null nicht als Argument und nicht als Rückgabe im Einsatz ist, kommt einer weiteren Eigenschaft zugute: Die API gestattet »flüssige« Ausdrücke, also kaskadierte Aufrufe, da viele Methoden die this-Referenz zurückgeben, so wie das auch von StringBuilder bekannt ist.

Zu diesen eher technischen Eigenschaften kommt eine neue Namensgebung hinzu, die sich von der Namensgebung der bekannten JavaBeans absetzt. So gibt es keine Konstruktoren und keine Setter (das brauchen die immutablen Klassen nicht), sondern neue Muster, die viele der neuen Typen aus der Date-Time-API einhalten:

Methode

Klassen-/Exemplarmethode

Grundsätzliche Bedeutung

now(…)

statisch

Liefert Objekt mit aktueller Zeit/aktuellem Datum.

ofXXX(…)

statisch

Erzeugt neue Objekte.

fromXXX(…)

statisch

Erzeugt neue Objekte aus anderen Repräsentationen.

parseXXX(…)

statisch

Erzeugt neues Objekt aus einer String-Repräsentation.

format(…)

Exemplar

Formatiert und liefert einen String.

getXXX(…)

Exemplar

Liefert Felder eines Objekts.

isXXX(…)

Exemplar

Fragt Status eines Objekts ab.

withXXX(…)

Exemplar

Liefert Kopie des Objekts mit einer geänderten Eigenschaft.

plusXXX(…)

Exemplar

Liefert Kopie des Objekts mit einer aufsummierten Eigenschaft.

minusXXX(…)

Exemplar

Liefert Kopie des Objekts mit einer reduzierten Eigenschaft.

toXXX()

Exemplar

Konvertiert Objekt in neuen Typ.

atXXX()

Exemplar

Kombiniert dieses Objekt mit einem anderen Objekt.

XXXInto()

Exemplar

Kombiniert eigenes Objekt mit einem anderen Zielobjekt.

Tabelle 13.5Namensmuster in der Date-Time-API

Die Methode now() haben wir schon in den ersten Beispielen verwendet, sie liefert zum Beispiel das aktuelle Datum. Weitere Erzeugermethoden sind die mit dem Präfix of, from oder with; Konstruktoren gibt es nicht. withXXX()-Methoden nehmen die Rolle der Setter ein.

Datumsklasse LocalDate

Ein Datum (ohne Zeitzone) repräsentiert die Klasse LocalDate. Damit lässt sich zum Beispiel ein Geburtsdatum repräsentieren.

Ein temporales Objekt kann über die statischen of(…)-Fabrikmethoden aufgebaut oder von einem anderen Objekt abgeleitet werden. Interessant sind die Methoden, die mit einem TemporalAdjuster arbeiten.

[zB]Beispiel

LocalDate today = LocalDate.now();
LocalDate nextMonday = today.with( TemporalAdjusters.next( DayOfWeek.SATURDAY ) );
System.out.printf( "Heute ist der %s, und frei ist am Samstag, den %s",
today, nextMonday );

Mit den Objekten in der Hand können wir diverse Getter nutzen und einzelne Felder erfragen, etwa getDayOfMonth(), getDayOfYear() (liefern int) oder getDayOfWeek(), das eine Aufzählung vom Typ DayOfWeek liefert, und getMonth(), das eine Aufzählung vom Typ Month liefert. Dazu kommen Methoden, die mit minusXXX(…) oder plusXXX(…) neue LocalDate-Objekte liefern, wenn zum Beispiel mit minusYear(long yearsToSubtract) eine Anzahl Jahre zurückgelaufen werden soll. Durch die Negation des Vorzeichens kann auch die jeweils entgegengesetzte Methode genutzt werden, sprich LocalDate.now().minusMonths(1) kommt zum gleichen Ergebnis wie LocalDate.now().plusMonths(-1). Die withXXX(…)-Methoden belegen ein Feld neu und liefern ein modifiziertes neues LocalDate-Objekt.

Von einem LocaleDate lassen sich andere temporale Objekte bilden, atTime(…) etwa liefert Methoden für LocalDateTime-Objekte, bei denen gewisse Zeit-Felder belegt sind. atTime(int hour, int minute) ist so ein Beispiel. Mit until(…) lässt sich eine Zeitdauer vom Typ Period liefern.

 


Ihr Kommentar

Wie hat Ihnen das <openbook> gefallen? Wir freuen uns immer über Ihre freundlichen und kritischen Rückmeldungen.

>> Zum Feedback-Formular
<< zurück
 Zum Katalog
Zum Katalog: Java ist auch eine Insel Java ist auch eine Insel
Jetzt bestellen

 Ihre Meinung?
Wie hat Ihnen das <openbook> gefallen?
Ihre Meinung

 Buchempfehlungen
Zum Katalog: Java SE 8 Standard-Bibliothek
Java SE 8 Standard-Bibliothek


Zum Katalog: Professionell entwickeln mit Java EE 7
Professionell entwickeln mit Java EE 7


Zum Katalog: Schrödinger programmiert Java
Schrödinger programmiert Java


Zum Katalog: Einführung in Java
Einführung in Java


Zum Katalog: Programmieren lernen mit Java
Programmieren lernen mit Java


Zum Katalog: Apps entwickeln für Android 5
Apps entwickeln für Android 5


Zum Katalog: Apps entwickeln mit Android Studio
Apps entwickeln mit Android Studio


 Shopping
Versandkostenfrei bestellen in Deutschland und Österreich
InfoInfo

 
 


Copyright © Rheinwerk Verlag GmbH 2016
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das <openbook> denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.

 
Nutzungsbestimmungen | Datenschutz | Impressum

Rheinwerk Verlag GmbH, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, service@rheinwerk-verlag.de