Advanced Java Services | java.time.Instant |
Die Klasse Instant repräsentiert einen Zeitpunkt auf der Zeitachse. Einmal gewählt ist er nicht veränderbar. Instanzen der Klasse Instant kann man nur über statische Methoden erzeugen, da die Klasse über keinen öffentlichen Konstruktor verfügt. Neben den sechs Factorymethoden gibt es noch drei Instantkonstanten. Da Instant sich an der GMT orientiert gibt es kein ZeitOffset und keine Zeitzonen.
Instant Konstanten und Factorymethoden | |
---|---|
Konstanten | Eigenschaft |
EPOCH | Constant for the 1970-01-01T00:00:00Z epoch |
MAX | The maximum supported Instant, '1000000000-12-31T23:59:59.999999999Z' |
MIN | The minimum supported Instant, '-1000000000-01-01T00:00Z' |
(statische) Factorymethoden | Eigenschaft |
now() | Obtains the current instant from the system clock. |
now(Clock clock) | Obtains the current instant from the specified clock. |
ofEpochMilli(long epochMilli) | Obtains an instance of Instant using milliseconds from the epoch of 1970-01-01T00:00:00Z. |
ofEpochSecond(long epochSecond) | Obtains an instance of Instant using seconds from the epoch of 1970-01-01T00:00:00Z. |
ofEpochSecond(long epochSecond, long nanoAdjustment) | Obtains an instance of Instant using seconds and nanosecond fraction from the epoch of 1970-01-01T00:00:00Z. |
parse(CharSequence text) | Obtains an instance of Instant from a text string such as 2007-12-03T10:15:30.00Z. |
from(TemporalAccessor datetime) | Obtains an instance of Instant from a text string such as 2007-12-03T10:15:30.00Z. |
Code Schnipsel
// now // aktuelle Uhrzeit Instant jetzt = Instant.now(); System.out.println("jetzt : " + jetzt); // 2014-06-28T15:44:01.415Z // now(Clock clock) // Clock = abstrakte Klasse zu der es keine standardimplementierung gibt // statische ofXxx-Methoden // (3) ofEpochSecond(long seconds) //Obtains an instance of Instant using milliseconds from the epoch of 1970-01-01T00:00:00Z. Instant epoch = Instant.ofEpochSecond(0); System.out.println("ofEpochSecond(0) : " + epoch); // Hier geht natürlich auch die Konstante System.out.println("Instant.EPOCH : " + Instant.EPOCH); System.out.println("--------------------------------------------------"); // 10 Jahre nach der EPOCH long tenYears = 10*365*24*60*60 + 2*24*60*60; // 2 Schalttage Instant tenYearsAfter = Instant.ofEpochSecond(tenYears); System.out.println("tenYearsAfter : " + tenYearsAfter); System.out.println("--------------------------------------------------"); // 10 Jahre vor der EPOCH long earlier = -(10*365*24*60*60 + 3*24*60*60); // 3 Schalttage //System.out.println(earlier); Instant twentyYearsEarlier = Instant.ofEpochSecond(earlier); System.out.println("tenYearsEarlier : " + twentyYearsEarlier); System.out.println("--------------------------------------------------"); // 10 Jahre vor der EPOCH mit milli long earlier2 = -(10L*365*24*60*60 + 3*24*60*60)*1000; // 3 Schalttage //System.out.println(earlier2); Instant twentyYearsEarlier2 = Instant.ofEpochMilli(earlier2); System.out.println("tenYearsEarlier(milli) : " + twentyYearsEarlier2); System.out.println("--------------------------------------------------"); // aufpassen, bei ofEpochMilli muß mit long gerechnet werden,
// (6) static Instant parse(CharSequence text) //Obtains an instance of Instant from a text string such as 2007-12-03T10:15:30.00Z. Instant frenchRevo = Instant.parse("1789-07-14T15:00:00.00Z"); // 1789, 7, 14 15 uhr); System.out.println("french revolution : " + frenchRevo); // // formate // millisekunden kann man weglassen, nicht aber sekunden, auch nicht das Z ! //Instant revo = Instant.parse("1789-07-14T"); // DateTimeParseException ! //java.time.format.DateTimeParseException: Text '1789-07-14T' could not be parsed at index 11 //Instant revo = Instant.parse("1789-07-14"); // DateTimeParseException ! //java.time.format.DateTimeParseException: Text '1789-07-14T' could not be parsed at index 11 Instant revo = Instant.parse("1789-07-14T15:00:00.000000009Z"); // 9 Nanosekunden letzte Stelle, dann // DateTimeParseException ! System.out.println(revo);
Unterstützt wird bei Instant nur ein Format der folgenden Form
yyyy-mm-ddThh:mm:ss.xxxxxxxxxZ"
Die Sekundenbruchteile können weggelassen werden, nicht aber die Sekunden und auch nicht das 'Z'. Ebenso muß die Stellenzahl genau eingehalten werden. Die folgende UTC-Formate führen zu einer DateTimeParseException.
"2014-05-26T16:46Z" "2014-W22" "2014-W22-1" "2014-146" "2014-05-26" "2014-06-28T04:41:58+00:00"
Mit isSupported(TemporalUnit unit) und isSupported(TemporalField field) kann man feststellen welche EnumKonstanten aus ChronoUnit bzw. ChronoField unterstützt werden. Das Codeschnipsel ergibt die in der Tabelle aufgeführten Werte.
// ChronoUnit Instant now = Instant.now(); for(ChronoUnit co : ChronoUnit.values()) { System.out.println(co + "\t" + now.isSupported(co) ); } // ChronoField for(ChronoField cf : ChronoField.values()) { System.out.println(cf + "\t" + now.isSupported(cf) ); }
Von Instant unterstütze Konstanten aus ChronoUnit und ChronoField | |
---|---|
ChronoUnit | |
ChronoUnit.NANOS ChronoUnit.MICROS ChronoUnit.MILLIS ChronoUnit.SECONDS ChronoUnit.MINUTES ChronoUnit.HOURS ChronoUnit.HALF_DAYS ChronoUnit.DAYS | |
ChronoField | |
ChronoField.NANO_OF_SECOND ChronoField.MICRO_OF_SECOND ChronoField.MILLI_OF_SECOND ChronoField.INSTANT_SECONDS |
from ist nur für OffsetDateTime und ZonedDateTime anwendbar und rechnet auf GMT um
java.time.OffsetDateTime -> java.time.Instant
// zum Vergleich Instant now = Instant.now(); System.out.println(now); System.out.println("-----------------------------------------------"); OffsetDateTime odt = OffsetDateTime.now(); System.out.println(odt); Instant fromOffset = Instant.from(odt); System.out.println(fromOffset);
java.time.ZonedDateTime -> java.time.Instant
// zum Vergleich Instant now = Instant.now(); System.out.println(now); System.out.println("-----------------------------------------------"); ZonedDateTime zdt = ZonedDateTime.now(); System.out.println(zdt); Instant fromZoned = Instant.from(zdt); System.out.println(fromZoned);
Ausgabe
UTC 2014-10-24T07:34:04.316Z ----------------------------------------------- ZDT 2014-10-24T09:34:04.410+02:00[Europe/Berlin] INST 2014-10-24T07:34:04.410Z ----------------------------------------------- ODT 2014-10-24T09:34:04.410+02:00 INST 2014-10-24T07:34:04.410Z
Aus LocalDateTime kann mit from kein Instant erzeugt werden:
//LocalDateTime ldt = LocalDateTime.now(); //Instant fromLocal = Instant.from(ldt); //java.time.DateTimeException: Unable to obtain Instant from TemporalAccessor: 2014-10-24T09:22:54.029 of type java.time.LocalDateTime //java.time.temporal.UnsupportedTemporalTypeException: Unsupported field: InstantSeconds
java.time.Instant -> java.time.OffsetDateTime
Instant now = Instant.now(); System.out.println(now); ZoneOffset zo = ZoneOffset.ofHours(7); OffsetDateTime odt = now.atOffset(zo); System.out.println(odt);
java.time.Instant -> java.time.ZonedDateTime
Instant now = Instant.now(); System.out.println(now); ZoneId java = ZoneId.of("Asia/Jakarta"); ZonedDateTime zdt = now.atZone(java); System.out.println("Java: " + zdt);
Ausgabe
2014-10-24T14:55:07.760Z Java: 2014-10-24T21:55:07.760+07:00[Asia/Jakarta] 2014-10-24T21:55:07.760+07:00
Es ist auch nicht schwer, alle möglichen Zeitzonen zu einem Offset zu finden. Die folgende kleine Methode ermittelt alle Zeitzonen zu einem übergebenen Offset
/** */ private static Set<String> getZonesFromOffset(int offHours) { Set<String> ids = ZoneId.getAvailableZoneIds(); TreeSet<String> zones = new TreeSet<>(); for(String id: ids) { ZoneOffset zo = ZoneId.of(id).getRules().getOffset(Instant.now()); if (zo.getTotalSeconds() == offHours*3600) { zones.add(id); } } return zones; }
Für einen Offset von +7 ergibt sich
Set<String> zones = getZonesFromOffset(7); for(String zone: zones) { System.out.println(zone); }
Ausgabe
Antarctica/Davis Asia/Bangkok Asia/Ho_Chi_Minh Asia/Hovd Asia/Jakarta Asia/Novokuznetsk Asia/Novosibirsk Asia/Omsk Asia/Phnom_Penh Asia/Pontianak Asia/Saigon Asia/Vientiane Etc/GMT-7 Indian/Christmas
Bei diesen Umwandlungen ist zu beachten, daß weder Date noch Calendar mit UTC-Zeit arbeiten, im Gegensatz zu Instant. Date und Calendar bringen die Uhrzeit der lokalen Einstellung des Rechners. Steht ein Rechner in Mitteleuropa, so liefert die Umwandlung von Instant nach Date oder Calendar im Sommer eine um zwei Stunden spätere Zeit als die UTC-Zeit, im Winter dann eine um eine Stunde spätere Zeit, denn die Basis für die UTC ist die Greenwich Mean Time. Bei der Umwandlung von Calendar bzw. Date nach Instant werden entsprechend zwei oder eine Stunde abgezogen.
java.util.Date -> java.time.Instant
Date jetzt = new Date(); Instant now = jetzt.toInstant(); // Methode in Date ab Java 1.8 // oder Instant now = Instant.ofEpochMilli(jetzt.getTime());
java.time.Instant -> java.util.Date
Instant now = Instant.now(); Date jetzt = Date.from(now); // statische Methode in Date ab Java 1.8 // oder Date jetzt = new Date(now.toEpochMilli());
java.util.Calendar -> java.time.Instant
Calendar jetzt = Calendar.getInstance(); Instant now = jetzt.toInstant(); // Methode in Calendar ab Java 1.8 // oder Instant now = Instant.ofEpochMilli(jetzt.getTimeInMillis());
java.time.Instant -> java.util.Calendar
Instant now = Instant.now(); Calendar jetzt = Calendar.getInstance(); jetzt.setTimeInMillis(now.toEpochMilli());
oder über ZonedDateTime
Instant now = Instant.now(); ZonedDateTime zdt = now.atZone(ZoneId.systemDefault() ); // Instant->
ZonedDateTime Calendar cal = GregorianCalendar.from(zdt); // ZonedDateTime->
(Gregorian) Calendar System.out.println("Calendar from Zoned: " + cal ); // 2015-07-14T11:27:15.652Z // UTC Zeit !!
Calendar jetzt = Calendar.getInstance();
GregorianCalendar greg = (GregorianCalendar)jetzt;
ZonedDateTime zdt = greg.toZonedDateTime();
ZonedDateTime zdt = ZonedDateTime.now();
System.out.println("Greg to Zoned : " + zdt); // 2015-07-14T17:44:35.377+02:00[Europe/Berlin]
GregorianCalendar greg = GregorianCalendar.from(zdt);
Instant instant = ...; ZoneOffset offset = ZoneOffset.systemDefault().getRules().getOffset(instant); OffsetDateTime odt = instant.atOffset(offset); oder ZoneId zoneId = ZoneId.systemDefault(); OffsetDateTime odt = OffsetDateTime.ofInstant(instant, zoneId);
OffsetDateTime odt = ...;
Instant inst = odt.toInstant();
Instant ins = ...;
ZonedDateTime zdt = ins.atZone(ZoneId.systemDefault());
ZonedDateTime zdt = ...;
Instant ins = zdt.toInstant();
OffsetDateTime odt = ...;
LocalDateTime ldt = odt.toLocalDateTime();
LocalDateTime ldt = ...; ZoneOffset offset = ZoneOffset.systemDefault().getRules().getOffset(ldt); OffsetDateTime odt = ldt.atOffset(offset); oder OffsetDateTime odt = OffsetDateTime.of(ldt, offset);
ZonedDateTime zdt = ...;
LocalDateTime ldt = zdt.toLocalDateTime();
LocalDateTime ldt = ...; ZonedDateTime zdt = ldt.atZone(ZoneId.systemDefault()); oder ZonedDateTime zdt = ZonedDateTime.of(ldt, ZoneId.systemDefault());