Java 8 hat eine neue java.time- API für die Arbeit mit Datum und Uhrzeit hinzugefügt ( JSR 310 ).
Ich habe Datum und Uhrzeit als Zeichenfolge (z "2014-04-08 12:30"
. B. ). Wie kann ich eine LocalDateTime
Instanz aus der angegebenen Zeichenfolge erhalten?
Nachdem ich mit dem LocalDateTime
Objekt gearbeitet habe: Wie kann ich die LocalDateTime
Instanz dann wieder in eine Zeichenfolge mit demselben Format wie oben konvertieren?
ZonedDateTime
eher eine als eine wollenLocalDateTime
. Der Name ist nicht intuitiv; dasLocal
bedeutet , jede Ortschaft im Allgemeinen eher als eine bestimmte Zeitzone. Als solches ist einLocalDateTime
Objekt nicht an die Zeitlinie gebunden. Um eine Bedeutung zu haben und einen bestimmten Moment in der Zeitleiste zu erhalten, müssen Sie eine Zeitzone anwenden.LocalDateTime
vs.ZonedDateTime
vs.OffsetDateTime
vs.Instant
vs.LocalDate
vs.LocalTime
, wie Sie ruhig bleiben können, warum es so kompliziert ist und wie Sie es beim ersten Schuss richtig machen.LocalDateTime
wäre , wäre es wahrscheinlich benannt wordenZonelessOffsetlessDateTime
.Antworten:
Datum und Uhrzeit analysieren
Um ein
LocalDateTime
Objekt aus einer Zeichenfolge zu erstellen , können Sie die statischeLocalDateTime.parse()
Methode verwenden. Es braucht einen String und einenDateTimeFormatter
als Parameter. MitDateTimeFormatter
wird das Datums- / Uhrzeitmuster angegeben.Formatieren von Datum und Uhrzeit
Um eine formatierte Zeichenfolge aus einem
LocalDateTime
Objekt zu erstellen , können Sie dieformat()
Methode verwenden.Beachten Sie, dass einige häufig verwendete Datums- / Uhrzeitformate als Konstanten in vordefiniert sind
DateTimeFormatter
. Beispiel: Wenn SieDateTimeFormatter.ISO_DATE_TIME
dieLocalDateTime
Instanz von oben formatieren, wird die Zeichenfolge angezeigt"1986-04-08T12:30:00"
.Die Methoden
parse()
undformat()
sind für alle datums- / zeitbezogenen Objekte verfügbar (z. B.LocalDate
oderZonedDateTime
).quelle
DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSX")
format()
die LocalDateTime-Klasse anstelle der Instanz aufzurufen? Zumindest das ist , was ich getan habe: Ich verwirrteDateTime
mitdateTime
im Beispiel oben.Sie können auch verwenden
LocalDate.parse()
oderLocalDateTime.parse()
auf einem ,String
ohne es mit einem Muster bereitstellt, wenn dieString
in ist ISO-8601 - Format .zum Beispiel,
Ausgabe ,
und
DateTimeFormatter
nur verwenden, wenn Sie sich mit anderen Datumsmustern befassen müssen.Im folgenden Beispiel steht dd MMM uuuu beispielsweise für den Tag des Monats (zwei Ziffern), drei Buchstaben des Monatsnamens (Jan, Feb, Mar, ...) und ein vierstelliges Jahr:
Ausgabe
Denken Sie auch daran, dass das
DateTimeFormatter
Objekt bidirektional ist. Es kann sowohl die Eingabe analysieren als auch die Ausgabe formatieren.Ausgabe
(Siehe vollständige Liste der Muster zum Formatieren und Analysieren von DateFormatter. )
quelle
2018-08-09 12:00:08
analysieren, aber wenn ich es analysiere, wird einT
hinzugefügt, das ich nicht benötige. Gibt es eine Möglichkeit, dies zu tun?yyyy-MM-dd hh:mm:ss
zum Parsen und Formatieren verwenden. Das T wird immer im Standardformat (ISO-8061) angezeigt, Sie können jedoch auch eigene Muster verwenden.Beide obigen Antworten erklären sehr gut die Frage nach String-Mustern. Nur für den Fall, dass Sie mit ISO 8601 arbeiten, müssen Sie sich nicht bewerben,
DateTimeFormatter
da LocalDateTime bereits darauf vorbereitet ist:Konvertieren Sie LocalDateTime in die Zeitzone ISO8601 String
Konvertieren Sie von einem ISO8601-String zurück in eine LocalDateTime
quelle
Das Parsen eines Strings mit Datum und Uhrzeit zu einem bestimmten Zeitpunkt (Java nennt es ein "
Instant
") ist ziemlich kompliziert. Java hat dies in mehreren Iterationen angegangen. Die neueste ein,java.time
undjava.time.chrono
, deckt nahezu alle Bedürfnisse (außer Zeitdilatation :)).Diese Komplexität bringt jedoch viel Verwirrung.
Der Schlüssel zum Verständnis der Datumsanalyse ist:
Warum hat Java so viele Möglichkeiten, ein Datum zu analysieren?
... und warum ist das
LocalDateTime
,ZonedDateTime
et al. so kompliziertEs gibt Zeitzonen . Eine Zeitzone ist im Grunde ein "Streifen" * [1] der Erdoberfläche, dessen Autoritäten den gleichen Regeln folgen, wann sie welchen Zeitversatz hat. Dies beinhaltet Sommerzeitregeln.
Die Zeitzonen ändern sich im Laufe der Zeit für verschiedene Bereiche, hauptsächlich basierend darauf, wer wen erobert. Und die Regeln einer Zeitzone ändern sich auch im Laufe der Zeit .
Es gibt Zeitversätze. Das ist nicht dasselbe wie Zeitzonen, weil eine Zeitzone zB "Prag" sein kann, aber das hat Sommerzeitversatz und Winterzeitversatz.
Wenn Sie einen Zeitstempel mit einer Zeitzone erhalten, kann der Versatz variieren, je nachdem, in welchem Teil des Jahres er sich befindet. Während der Schaltstunde kann der Zeitstempel zwei verschiedene Zeiten bedeuten, sodass er ohne zusätzliche Informationen nicht zuverlässig sein kann umgewandelt.
Hinweis: Mit Zeitstempel meine ich "eine Zeichenfolge, die ein Datum und / oder eine Uhrzeit enthält, optional mit einer Zeitzone und / oder einem Zeitversatz."
Mehrere Zeitzonen können für bestimmte Zeiträume denselben Zeitversatz verwenden. Beispielsweise entspricht die GMT / UTC-Zeitzone der Zeitzone "London", wenn der Sommerzeitversatz nicht wirksam ist.
Um es etwas komplizierter zu machen (aber das ist für Ihren Anwendungsfall nicht zu wichtig):
2040-12-31 24:00:00
Möglicherweise handelt es sich also um eine gültige Datums- und Uhrzeitangabe.) Dies erfordert regelmäßige Aktualisierungen der Metadaten, die Systeme verwenden, um die Datumskonvertierungen richtig durchzuführen. Unter Linux erhalten Sie beispielsweise regelmäßig Updates für die Java-Pakete, einschließlich dieser neuen Daten.Die Aktualisierungen behalten nicht immer das vorherige Verhalten für historische und zukünftige Zeitstempel bei. Daher kann es vorkommen, dass das Parsen der beiden Zeitstempel um die Änderung einer Zeitzone herum, wenn sie verglichen werden , zu unterschiedlichen Ergebnissen führt, wenn sie auf verschiedenen Versionen der Software ausgeführt werden. Dies gilt auch für den Vergleich zwischen der betroffenen Zeitzone und einer anderen Zeitzone.
Sollte dies zu einem Fehler in Ihrer Software führen, sollten Sie einen Zeitstempel verwenden, für den keine so komplizierten Regeln gelten, z. B. einen UNIX-Zeitstempel .
Aufgrund von 7 können wir für zukünftige Daten Daten nicht mit Sicherheit genau konvertieren. So kann beispielsweise die aktuelle Analyse von
8524-02-17 12:00:00
einige Sekunden nach der zukünftigen Analyse verschoben sein.Die APIs von JDK haben sich mit den aktuellen Anforderungen weiterentwickelt
java.util.Date
was ein bisschen naiv war, vorausgesetzt, es gibt nur das Jahr, den Monat, den Tag und die Uhrzeit. Dies reichte schnell nicht aus.java.sql.Date
eingeführt wurde, mit seinen eigenen Einschränkungen.Calendar
API eingeführt.Wie man damit in Java umgeht
java.time
Bestimmen Sie, auf welchen Typ ein Zeitstempel analysiert werden soll
Wenn Sie eine Zeitstempelzeichenfolge verwenden, müssen Sie wissen, welche Informationen darin enthalten sind. Dies ist der entscheidende Punkt. Wenn Sie dies nicht richtig verstehen, erhalten Sie kryptische Ausnahmen wie "Instant kann nicht erstellt werden" oder "Zonenversatz fehlt" oder "Unbekannte Zonen-ID" usw.
Enthält es das Datum und die Uhrzeit?
Hat es einen Zeitversatz?
Ein Zeitversatz ist das
+hh:mm
Teil. Manchmal+00:00
kann esZ
als "Zulu-Zeit",UTC
als koordinierte Weltzeit oderGMT
als mittlere Greenwich-Zeit ersetzt werden. Diese legen auch die Zeitzone fest.Für diese Zeitstempel verwenden Sie
OffsetDateTime
.Hat es eine Zeitzone?
Für diese Zeitstempel verwenden Sie
ZonedDateTime
.Die Zone wird entweder durch angegeben
Die Liste der Zeitzonen wird von einer "TZ-Datenbank" zusammengestellt , die von ICAAN unterstützt wird.
Laut
ZoneId
javadoc können die Zonen-IDs auch irgendwie alsZ
und versetzt angegeben werden. Ich bin mir nicht sicher, wie dies realen Zonen zugeordnet wird. Wenn der Zeitstempel, der nur eine TZ hat, in eine Schaltstunde der Zeitversatzänderung fällt, ist er mehrdeutig und die Interpretation ist Gegenstand vonResolverStyle
(siehe unten).Wenn dies nicht der Fall ist , wird der fehlende Kontext angenommen oder vernachlässigt. Und der Verbraucher muss sich entscheiden. Es muss also analysiert
LocalDateTime
und konvertiert werden,OffsetDateTime
indem die fehlenden Informationen hinzugefügt werden:Duration
) oder wenn Sie es nicht wissen und es nicht wirklich wichtig ist (z. B. lokaler Busfahrplan).Teilzeitinformationen
LocalDate
,LocalTime
,OffsetTime
,MonthDay
,Year
, oderYearMonth
aus ihm heraus.Wenn Sie die vollständigen Informationen haben, können Sie eine erhalten
java.time.Instant
. Dies wird auch intern zum Konvertieren zwischenOffsetDateTime
und verwendetZonedDateTime
.Finden Sie heraus, wie Sie es analysieren können
Es gibt eine umfangreiche Dokumentation, in
DateTimeFormatter
der sowohl eine Zeitstempelzeichenfolge analysiert als auch eine Zeichenfolge formatiert werden kann.Die vorgefertigten
DateTimeFormatter
s sollten mehr als alle Standard-Zeitstempelformate abdecken.ISO_INSTANT
Kann zum Beispiel analysieren2011-12-03T10:15:30.123457Z
.Wenn Sie ein spezielles Format haben, können Sie Ihren eigenen DateTimeFormatter (der auch ein Parser ist) erstellen .
Ich empfehle, sich den Quellcode von anzuschauen
DateTimeFormatter
und sich inspirieren zu lassen, wie man einen mit erstelltDateTimeFormatterBuilder
.ResolverStyle
Sehen Sie sich während Ihres Aufenthalts auch an, welche Steuerelemente für die Formate und mehrdeutigen Informationen LENIENT, SMART oder STRICT sind.TemporalAccessor
Der häufigste Fehler besteht nun darin, auf die Komplexität von einzugehen
TemporalAccessor
. Dies kommt davon, wie die Entwickler verwendet wurden, um damit zu arbeitenSimpleDateFormatter.parse(String)
. Richtig,DateTimeFormatter.parse("...")
gibt dirTemporalAccessor
.Ausgestattet mit den Kenntnissen aus dem vorherigen Abschnitt können Sie jedoch bequem den Typ analysieren, den Sie benötigen:
Das brauchst du eigentlich auch
DateTimeFormatter
nicht. Die Typen, die Sie analysieren möchten, haben dieparse(String)
Methoden.In Bezug auf
TemporalAccessor
, können Sie es verwenden , wenn Sie eine vage Vorstellung davon haben , welche Informationen es in der Zeichenfolge ist, und wollen zur Laufzeit entscheiden.Ich hoffe, ich habe etwas Licht des Verstehens auf deine Seele geworfen :)
Hinweis: Es gibt einen Backport von
java.time
Java 6 und 7: ThreeTen-Backport . Für Android hat es ThreeTenABP .[1] Nicht nur, dass es sich nicht um Streifen handelt, sondern auch um einige seltsame Extreme. Beispielsweise haben einige benachbarte Pazifikinseln Zeitzonen von +14: 00 und -11: 00. Das heißt, während es auf einer Insel den 1. Mai um 15 Uhr gibt, ist es auf einer anderen Insel noch nicht der 30. April um 12 Uhr (wenn ich richtig gezählt habe :))
quelle
ERHALTEN SIE DIE AKTUELLE UTC-ZEIT IM ERFORDERLICHEN FORMAT
quelle
Ich fand es wunderbar, mehrere Varianten des Datums-Zeit-Formats wie folgt abzudecken:
quelle