webentwicklung-frage-antwort-db.com.de

Gibt es eine Möglichkeit, ZoneId in Java 8 in ZoneOffset zu konvertieren?

Ich habe eine zweite Epoche und eine zoneId von method1.Es kann in LocalDateTime mit der System-Standard-zoneId konvertiert werden, aber ich finde nicht den Weg, Epoche in LocalDateTime von method2 zu konvertieren, da es keinen ZoneOffset.systemDefault gibt .

import Java.time.{Instant, LocalDateTime, ZoneId, ZoneOffset}

val epochSecond = System.currentTimeMillis() / 1000

LocalDateTime.ofInstant(Instant.ofEpochSecond(epochSecond), ZoneId.systemDefault())//method1
LocalDateTime.ofEpochSecond(epochSecond, 0, ZoneOffset.MAX)//method2
51
Renkai

So erhalten Sie ZoneOffset von ZoneId:

Instant instant = Instant.now(); //can be LocalDateTime
ZoneId systemZone = ZoneId.systemDefault(); // my timezone
ZoneOffset currentOffsetForMyZone = systemZone.getRules().getOffset(instant);

NB: ZoneId kann je nach Zeitpunkt und Geschichte des jeweiligen Ortes einen unterschiedlichen Versatz haben. Die Auswahl verschiedener Instants würde also zu unterschiedlichen Offsets führen.

67

Es gibt keine Eins-zu-Eins-Zuordnung. Eine ZoneId definiert eine geografische Ausdehnung, in der im Laufe der Zeit eine Reihe unterschiedlicher ZoneOffsets verwendet wird. Wenn die Zeitzone Sommerzeit verwendet, unterscheidet sich das ZoneOffset zwischen Sommer und Winter.

Außerdem können sich die Sommerzeitregeln im Laufe der Zeit geändert haben, so dass sich die ZoneOffset z. 13/10/2015 im Vergleich zu 13/10/1980.

Das ZoneOffset für eine ZoneId kann also nur für einen bestimmten Instant gefunden werden.

Siehe auch https://en.wikipedia.org/wiki/Tz_database

33
Geert Pante

tl; dr

ZonedDateTime.now( 
    ZoneId.of( "America/Montreal" ) 
)

… Der aktuellen Standardzeitzone…

ZonedDateTime.now( 
    ZoneId.systemDefault() 
)

Einzelheiten

Das Answer by Stanislav Bshkyrtsev beantwortet Ihre Frage richtig und direkt.

Es gibt jedoch größere Probleme, wie in der Antwort von Jon Skeet vorgeschlagen.

LocalDateTime

Ich kann Epoch second nicht in LocalDateTime konvertieren

LocalDateTime hat absichtlich keine Vorstellung von Zeitzone oder Offset von UTC. Wahrscheinlich nicht, was du willst. Das Local… Bedeutet eine beliebige Lokalität, keine bestimmte Lokalität. Diese Klasse stellt keinen Moment dar, sondern nur potenzielle Momente in einem Bereich von etwa 26 bis 27 Stunden (dem Bereich der Zeitzonen) um die Welt).

Instant

Sie müssen nicht mit "Epoche Sekunden" beginnen, wenn Sie die aktuelle Uhrzeit abrufen möchten. Holen Sie sich den aktuellen Instant. Die Klasse Instant repräsentiert einen Moment auf der Zeitachse in [~ # ~] utc [~ # ~] mit einer Auflösung von Nanosekunden (bis zu neun (9) Stellen eines Dezimalbruchs).

Instant instant = Instant.now();

Innerhalb dieses Instant ist eine Anzahl von Nanosekunden - from-Epoch. Aber das interessiert uns nicht wirklich.

ZonedDateTime

Wenn Sie diesen Moment durch die Linse der Wanduhrzeit einer bestimmten Region sehen möchten, wenden Sie ein ZoneId an, um ein ZonedDateTime zu erhalten.

ZoneId z = ZoneId.of( "Europe/Paris" );
ZonedDateTime zdt = instant.atZone( z );

Als Abkürzung können Sie direkt zu ZonedDateTime gehen.

ZonedDateTime zdt = ZonedDateTime.now( z );  

Ein ZonedDateTime enthält ein Instant. Rufen Sie zdt.toInstant() auf, um den gleichen Zeitpunkt wie einen Grundwert in [~ # ~] utc [~ # ~] zu erhalten. Gleiche Anzahl von Nanosekunden seit der Epoche, entweder als ZonedDateTime oder als Instant.

Sekunden seit der Zeit angegeben

Wenn Sie eine Anzahl von Sekunden seit der Epoche erhalten und die Epoche der erste Moment von 1970 in [~ # ~] utc [~ # ~] (1970-01-01T00:00:00Z), Dann tragen Sie diese Nummer in Instant ein.

long secondsSinceEpoch = 1_484_063_246L ;
Instant instant = Instant.ofEpochSecond( secondsSinceEpoch ) ;

Table of date-time types in Java, both modern and legacy.


Über Java.time

Das Java.time Framework ist in Java 8 und höher integriert. Diese Klassen ersetzen das lästige alte Legacy Datum-Zeit-Klassen wie Java.util.Date , Calendar , & SimpleDateFormat .

Weitere Informationen finden Sie im Oracle Tutorial . Durchsuchen Sie Stack Overflow nach vielen Beispielen und Erklärungen. Die Spezifikation lautet JSR 310 .

Das Joda-Time -Projekt, das sich jetzt im Wartungsmodus befindet, rät zur Migration nach die Java.time Klassen.

Sie können Java.time Objekte direkt mit Ihrer Datenbank austauschen. Verwenden Sie einen JDBC-Treiber , der mit JDBC 4.2 oder höher kompatibel ist. Keine Notwendigkeit für Zeichenketten, keine Notwendigkeit für Klassen Java.sql.*.

Woher bekommen Sie die Java.time-Klassen?

Das Projekt ThreeTen-Extra erweitert Java.time um zusätzliche Klassen. Dieses Projekt ist ein Testfeld für mögliche zukünftige Ergänzungen von Java.time. Hier finden Sie möglicherweise einige nützliche Klassen wie Interval , YearWeek , YearQuarter und more .

20
Basil Bourque

Wie in der Dokumentation heißt: "Dies ist in erster Linie für Konvertierungen auf niedriger Ebene und nicht für die allgemeine Verwendung von Anwendungen gedacht."

Über Instant zu gehen ist für mich absolut sinnvoll - Ihre zweite Epoche ist tatsächlich eine andere Darstellung einer Instant, konvertieren Sie sie in eine Instant und konvertieren Sie diese dann in eine bestimmte Zeitzone.

8
Jon Skeet

Ich hoffe, die ersten beiden Zeilen meiner Lösung sind hilfreich. Mein Problem war, dass ich eine LocalDateTime und den Namen einer Zeitzone hatte, und ich brauchte eine instant, damit ich einen Java.util.Date bauen konnte, weil MongoDB das wollte. Mein Code ist Scala, aber Java ist hier so nah. Ich denke, es sollte kein Problem sein, es zu verstehen:

val zid = ZoneId.of(tzName)                                // "America/Los_Angeles"
val zo: ZoneOffset = zid.getRules.getOffset(localDateTime) // ⇒ -07:00
                                         // 2017-03-16T18:03

val odt = OffsetDateTime.of(localDateTime, zo) // ⇒ 2017-03-16T18:03:00-07:00
val instant = odt.toInstant                    // ⇒ 2017-03-17T01:03:00Z
val issued = Date.from(instant)
6
gknauth

Das Folgende gibt die Zeit in Millisekunden zurück, die UTC hinzugefügt werden muss, um die Standardzeit in dieser Zeitzone zu erhalten:

TimeZone.getTimeZone(ZoneId.of("Europe/Amsterdam")).getRawOffset()
0
Jelmer