Mit Java8 wissen wir, dass die Verwendung ZoneId.default()
den Systemstandard erreichen kann ZoneId
, aber wie kann man den Standard erhalten ZoneOffset
?
Ich sehe, dass a ZoneId
einige "Regeln" hat und jede Regel a hat. Bedeutet das ZoneOffset
, dass a ZoneId
mehr als eine haben kann ZoneOffset
?
java
java-8
timezone
timezone-offset
FredSuvn
quelle
quelle
ZoneOffset.systemDefault()
ZoneOffset.systemDefault()
gibt jedoch a zurückZoneId
.ZoneOffset current = zone.getRules().getOffset(instant)
America/Los_Angeles
bewirkt, dass der Versatz-08:00
aktuell ist, sich jedoch-07:00
im Sommer ändert . Sie können also keinen Offset anfordern, ohne zu sagen, wann und für welche Zeitzone . Weitere Informationen finden Sie in meiner Antwort .Antworten:
tl; dr
Sie sollten jedoch wahrscheinlich eher eine Zeitzone als nur einen Versatz von UTC verwenden.
Versatz gegen Zeitzone
Ein Versatz von UTC besteht lediglich aus einer Anzahl von Stunden, Minuten und Sekunden - nichts weiter. Bedeutet beispielsweise
-08:00
acht Stunden hinter der UTC und+05:45
fünf Stunden und fünfundvierzig Minuten vor der UTC .Eine Zeitzone ist eine Geschichte vergangener, gegenwärtiger und zukünftiger Änderungen des Versatzes , den die Menschen einer bestimmten Region verwenden. Anomalien wie die Sommerzeit (DST), die zu Verschiebungen des Versatzes über bestimmte Zeiträume führen, werden im Laufe der Zeit verfolgt, in der Vergangenheit und in der Zukunft, wenn Politiker geplante Änderungen angekündigt haben.
Verwenden Sie daher besser eine Zone, wenn dies bekannt ist.
Der Versatz für jede Region variiert im Laufe der Zeit. Beispielsweise verschiebt die Sommerzeit in den USA den Versatz für etwa ein halbes Jahr um eine Stunde und stellt diese Stunde dann in der anderen Jahreshälfte wieder auf den Versatz zurück. Der gesamte Zweck einer Zeitzone besteht darin, diese Verschiebungen im Versatz zu dokumentieren.
Es macht also wirklich keinen Sinn, nach einem Offset ohne Datum und Uhrzeit zu fragen . In einem
America/Los_Angeles
Teil dieses Jahres ist der Offset beispielsweise-08:00
in einem anderen Teil des Jahres-07:00
während der Sommerzeit.OffsetDateTime
Geben wir also einen Moment als an
OffsetDateTime
und extrahieren Sie dann denZoneOffset
.Diese
now
Methode wendet implizit die aktuelle Standardzeitzone der JVM an. Ich schlage vor, dass Sie dies immer explizit machen, indem Sie Ihre gewünschte / erwartete Zeitzone angeben. Auch wenn Sie die aktuelle Standardzone möchten, sagen Sie dies ausdrücklich, um Ihre Absichten klar zu machen. Beseitigen Sie die Unklarheit darüber, ob Sie die Standardeinstellung beabsichtigt haben oder die Zeitzone nicht berücksichtigt haben, wie dies bei Programmierern so häufig der Fall ist. Rufen Sie anZoneId.systemDefault
.Eine Warnung bezüglich der Abhängigkeit von der Standardzone: Diese Standardeinstellung kann jederzeit durch einen beliebigen Code in einem beliebigen Thread innerhalb der JVM geändert werden. Wenn wichtig, fragen Sie den Benutzer nach der beabsichtigten Zeitzone.
Sie können den Versatz nach seiner Zeitdauer als Gesamtanzahl von Sekunden fragen.
int offsetSeconds = zoneOffset.getTotalSeconds ();
ZonedDateTime
Ein weiteres Beispiel: Vielleicht möchten Sie wissen, wie hoch der Offset am diesjährigen Weihnachtstag in Québec sein wird. Geben Sie die Zeitzone an
America/Montreal
, holen Sie sich aZonedDateTime
und fragen Sie nach dem Versatz alsZoneOffset
Objekt.ZoneId z = ZoneId.of( "America/Montreal" ); LocalDate ld = LocalDate.of( 2017 , 12 , 25 ); ZonedDateTime zdtXmas = ld.atStartOfDay( z ); ZoneOffset zoneOffsetXmas = zdtXmas.getOffset();
ZoneId
Wie im Kommentar von yanys vorgeschlagen, können Sie a
ZoneId
für eine bestimmte Person abfragen,ZoneOffset
indem Sie einen Moment alsInstant
. DieInstant
Klasse repräsentiert einen Moment auf der Zeitachse in UTC mit einer Auflösung von Nanosekunden (bis zu neun (9) Stellen eines Dezimalbruchs).Dies ist nur eine weitere Route zum selben Ziel. Genau wie bei
OffsetDateTime
undZonedDateTime
oben diskutiert geben wir (a) eine Zeitzone und (b) einen Moment an.Sehen Sie den Code all dieser Beispiele live auf IdeOne.com .
ZoneOffset.systemDefault
- Bug oder Feature?Die
ZoneOffset
Klasse, eine Unterklasse vonZoneId
, wird als Erbe dersystemDefault
Methode dokumentiert . Dies funktioniert jedoch nicht wirklich.ZoneOffset zoneOffset = ZoneOffset.systemDefault() ; // Fails to compile.
Ich bin mir nicht sicher, ob es sich bei diesem Kompilierungsfehler um einen Fehler oder eine Funktion handelt. Wie oben erläutert, scheint es mir nicht sinnvoll zu sein, jemals nach einem Standardversatz mit Datum und Uhrzeit zu fragen. Vielleicht
ZoneOffset.systemDefault
sollte dies tatsächlich fehlschlagen. In der Dokumentation sollte dies jedoch mit einer Erklärung angegeben werden.Ich habe versucht, einen Fehler zu melden, wenn das Dokument dieses Problem nicht behoben hat, habe jedoch aufgegeben und konnte nicht feststellen, wo und wie ein solcher Fehlerbericht eingereicht werden soll.
Sonnenzeit versus politische Zeit
Ein bisschen mehr über Offsets und Zeitzonen…
Sonnenzeit seit der Vorgeschichte verwendet, jeden Tag Tracking mit der Feststellung , wenn die Sonne direkt über ist. Stecke einen Stock in den Boden und beobachte seinen Schatten. Wenn der Schatten am kürzesten ist, wenn der Schatten eher zu wachsen als zu schrumpfen beginnt, dann wissen Sie, dass es jetzt Mittag ist. Formalisieren Sie dies mit einer Sonnenuhr , um den Stundenablauf zu verfolgen.
Mit der Sonnenzeit, wenn Sie von Stadt zu Stadt nach Westen reisen, kommt der Mittag etwas später. Wenn Sie nach Osten gehen, kommt der Mittag etwas früher. So hat jede Stadt ihren eigenen Mittag, der nur mit Städten im Norden und Süden auf derselben Länge geteilt wird.
Die Sonnenzeit wurde in der Neuzeit weitgehend aufgegeben. Als Züge, Telegraphen und Telefone eintrafen, musste auch zeitlich koordiniert werden. So wurde ein Punkt für die nahe Sonnenzeit des Mittags ausgewählt, und ein großer Landstrich, der so viele Meilen westlich und östlich liegt, soll alle 12:00 Uhr auf der Uhr teilen, die gleiche Anzahl von Stunden vor uns oder hinter der Greenwich Prime Meridian Linie . So begann die Tradition, dass an jeder Haltestelle an prominenter Stelle eine Uhr angezeigt wurde, um die Stadt über die Standardzeit für ihre größere Region und nicht über die Sonnenzeit für ihre eigene Stadt zu informieren . Im Allgemeinen Städte in der westlichen Rand dieser Zeitzone Region ihre Bahnhof Uhr sehen lesen 00.00 ein wenig vorDie Sonne steht über ihnen. Die Uhren in Städten am östlichen Rand der Region zeigen kurz nach Sonnenaufgang 12:00 Uhr an .
Politiker auf der ganzen Welt zeigten eine Vorliebe dafür, die Offset (s) ihrer Gerichtsbarkeit zu ändern. Die Gründe variieren, wie Diplomatie, Krieg und Besatzung und die Albernheit der Sommerzeit (DST) . Die Gründe variieren, aber ihre Änderungen kommen mit überraschender Häufigkeit. Eine Zeitzone ist ein Name, der einer Region gegeben wird, um den Verlauf solcher Änderungen zu verfolgen. Ein Versatz von UTC ist also nur eine Anzahl von Stunden-Minuten-Sekunden vor oder hinter dem Nullmeridian. Eine Zeitzone ist viel mehr: eine Geschichte vergangener, gegenwärtiger und zukünftiger Veränderungen der Offsets einer bestimmten Region. Während zwei benachbarte Regionen heute möglicherweise denselben Offset von UTC haben, können sie sich in der Vergangenheit oder Zukunft je nach den unterschiedlichen Launen oder der Logik ihrer Politiker unterscheiden.
Dies bedeutet, dass die von Politikern definierte moderne Zeiterfassung wenig mit der Geographie zu tun hat. Zum Beispiel hat das riesige Land Indien heute eine einzige Zeitzone (Offset von UTC von +05: 30). So ist der Sonnenmittag (Sonne direkt über Ihrem Kopf) an verschiedenen Orten auf dem riesigen Subkontinent Stunden voneinander entfernt. Die indischen Politiker beschlossen dies, um zur Vereinheitlichung ihrer vielfältigen Demokratie beizutragen. In anderen Beispielen auf der ganzen Welt sehen wir, dass Regionen ihre Zeitzone als Symbol für internationale Beziehungen verwenden, z. B. um sich von ihrem beleidigenden Nachbarland zu unterscheiden, oder dass sie dieselbe Zone als Nachbar wählen, wenn die Beziehungen auftauen, wie sich kürzlich in Nordkorea geändert hat Südkorea. Heutzutage ist die Sonnenzeit nur eine von mehreren Überlegungen bei der Zeiterfassung.
Über java.time
Das java.time- Framework ist in Java 8 und höher integriert. Diese Klassen verdrängen die lästigen alten Legacy - Datum-Zeit - Klassen wie
java.util.Date
,Calendar
, &SimpleDateFormat
.Weitere Informationen finden Sie im Oracle-Lernprogramm . Suchen Sie im Stapelüberlauf nach vielen Beispielen und Erklärungen. Die Spezifikation ist JSR 310 .
Das Joda-Time- Projekt, das sich jetzt im Wartungsmodus befindet , empfiehlt die Migration zu den Klassen java.time .
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 Zeichenfolgen, keine Notwendigkeit für
java.sql.*
Klassen. Hibernate 5 und JPA 2.2 unterstützen java.time .Woher bekomme ich die java.time-Klassen?
quelle
+03:00
). Politiker nehmen solche Änderungen häufig vor, oft ohne Vorankündigung. Dies führt dazu, dass die Benutzer sich bemühen, die 'tzdata'-Datenbankliste ihrer Computer mit den Zonendefinitionen zu aktualisieren.zone.getRules().getOffset(instant)
zusätzliche Anomalien zum erfassten Versatz manuell hinzufügen müssen, z. B. die Sommerzeit. Der von zurückgegebene OffsetgetOffset(instant)
ist bereits die genaue Anzahl von Stunden, Minuten und Sekunden, die zu diesem Zeitpunkt von GMT versetzt wurden. (Ich dachte immer, der Versatz sei nur der geografische Versatz, der beschreibt, wie viel früher / später die Sonne in dieser Region aufgeht, aber er berücksichtigt tatsächlich alle Regeln.)Abhängig von Ihrem Ziel können Sie möglicherweise vollständig umgehen
ZoneOffset
.Angenommen, Sie benötigen nur eine
ZoneOffset
für z. B.LocalDateTime.ofEpochSecond()
können Sie ersetzenZoneOffset offset = OffsetDateTime.now().getOffset(); LocalDateTime dt1 = LocalDateTime.ofEpochSecond(seconds, 0, offset);
mit
wo
dt1.equals(dt2)
isttrue
.quelle