Advanced   Java   Services java.time.Instant


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
KonstantenEigenschaft
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) FactorymethodenEigenschaft
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.


now()- und of()

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,

parse()
// (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);

Das Format für parse()

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"

isSupported()

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() [Konvertierungen von OffsetDateTime oder ZoneddateTime nach Instant]

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

atOffset() und atZone() [Konvertierungen von Instant nach OffsetDateTime oder ZonedDateTime]

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










Konvertierungen zu Calendar und Date

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 !!

Gregorian Calender <-> ZonedDateTime

Gregorian Calender -> ZonedDateTime
Calendar jetzt = Calendar.getInstance();
GregorianCalendar greg = (GregorianCalendar)jetzt;
ZonedDateTime zdt = greg.toZonedDateTime();

ZonedDateTime -> Gregorian Calender
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);

Konvertierungen zwischen den neuen Zeittypen

Instant <-> OffsetDateTime

Instant -> OffsetDateTime
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 -> Instant
OffsetDateTime odt = ...;
Instant inst = odt.toInstant();

Instant <-> ZonedDateTime

Instant -> ZonedDateTime
Instant ins = ...;

ZonedDateTime zdt = ins.atZone(ZoneId.systemDefault());

ZonedDateTime -> Instant
ZonedDateTime zdt = ...;

Instant ins = zdt.toInstant();

OffsetDateTime <-> LocalDateTime

OffsetDateTime -> LocalDateTime
OffsetDateTime odt = ...;

LocalDateTime ldt = odt.toLocalDateTime();

LocalDateTime -> OffsetDateTime
LocalDateTime ldt = ...;

ZoneOffset offset = ZoneOffset.systemDefault().getRules().getOffset(ldt);
OffsetDateTime odt = ldt.atOffset(offset);
oder
OffsetDateTime odt = OffsetDateTime.of(ldt, offset);

ZonedDateTime <-> LocalDateTime

ZonedDateTime -> LocalDateTime
ZonedDateTime zdt = ...;

LocalDateTime ldt = zdt.toLocalDateTime();

LocalDateTime -> ZonedDateTime
LocalDateTime ldt = ...;

ZonedDateTime zdt = ldt.atZone(ZoneId.systemDefault());
oder
ZonedDateTime zdt = ZonedDateTime.of(ldt, ZoneId.systemDefault());