Ich habe ein Datenbankfeld, das ein Rohdatenfeld enthält (gespeichert als Zeichendaten), zB
Freitag, 26. September 2008 20.30 Uhr östliche Sommerzeit
Ich kann dies einfach als Date analysieren, mit SimpleDateFormat
%Vor% Was ich tun möchte, ist ein TimeZone-Objekt aus dieser Zeichenfolge zu extrahieren. Die Standard-Zeitzone in der JVM, in der diese Anwendung ausgeführt wird, ist GMT, daher kann ich .getTimezoneOffset()
nicht von der oben analysierten Date
verwenden (weil sie die Standard-Zeitzone zurückgibt).
Neben dem Token der rohen Zeichenkette und dem Finden der Startposition der Zeitzonen-Zeichenkette (da ich weiß, dass das Format immer EEEE, MMMM dd, yyyy hh:mm aa zzzz
ist) gibt es eine Möglichkeit, die DateFormat / SimpleDateFormat / Date / Calendar API zu verwenden, um ein TimeZone-Objekt zu extrahieren - welches wird die gleiche TimeZone wie die Zeichenfolge haben, die ich auseinander mit DateFormat.parse()
zerlegt habe?
Eine Sache, die mich an Date
vs Calendar
in der Java API stört ist, dass Calendar
Date
an allen Stellen ersetzen soll ... aber dann haben sie entschieden, oh hey, lass uns noch% co_de benutzen % in den Klassen Date
.
Ich habe Folgendes gefunden:
%Vor%Erzeugt Folgendes:
%Vor%Ich fand das tatsächlich etwas überraschend. Aber ich denke, das zeigt, dass die Antwort auf Ihre Frage darin besteht, getTimeZone nach dem Parsen einfach im Formatierer aufzurufen.
Bearbeiten: Das obige wurde mit Suns JDK 1.6 ausgeführt.
@Ed Thomas:
Ich habe etwas sehr ähnliches wie Ihr Beispiel versucht und ich bekomme sehr unterschiedliche Ergebnisse:
%Vor%Ausgabe:
Die Standardzeitzone ist: Eastern Standard Time
DateFormat Zeitzone vor dem Parsen: Eastern Standard Time
Parsed [Freitag, 26. September 2008 20:30 Uhr Pacific Standard Time] bis Datum: Sa Sep 27 00:30:00 EDT 2008
DateFormat Zeitzone nach dem Parsen: Eastern Standard Time
Scheint so, als ob DateFormat.getTimeZone()
die gleiche Zeitzone vor und nach der parse()
... zurückgibt, auch wenn ich eine explizite setTimeZone()
vor Aufruf von parse()
einreiche.
Wenn wir uns die Quelle für DateFormat und SimpleDateFormat anschauen, scheint getTimeZone()
nur die Zeitzone des zugrunde liegenden Kalenders zurück zu geben, die standardmäßig auf den Kalender der Standard-Locale / TimeZone gesetzt wird, außer Sie geben eine bestimmte an / p>
Nun, als eine Teillösung können Sie eine RegEx-Übereinstimmung verwenden, um die Zeitzone zu erhalten, da Sie immer den gleichen Text davor haben werden. AM oder PM.
Ich weiß nicht genug über Java-Zeitzonen, um den letzten Teil davon zu bekommen.
Der Hauptunterschied zwischen Date und Calendar besteht darin, dass Date nur ein Wertobjekt ohne Methoden zum Ändern ist. So ist es für das Speichern einer Datums- / Zeitinformation irgendwo gedacht. Wenn Sie ein Kalenderobjekt verwenden, können Sie es ändern, nachdem es auf eine persistente Entität festgelegt wurde, die eine Geschäftslogik mit den Datums- / Uhrzeitinformationen ausführt. Das ist sehr gefährlich, weil das Wesen diese Veränderung nicht erkennen kann. Die Calendar-Klasse ist für Operationen an Datum / Uhrzeit gedacht, wie das Hinzufügen von Tagen oder ähnlichem.
Um mit Ihrem Beispiel herumzuspielen, bekomme ich Folgendes:
%Vor%Ausgabe:
sun.util.calendar.ZoneInfo [id="Europa / Berlin" ... sun.util.calendar.ZoneInfo [id="Afrika / Addis_Ababa" ...
Ist das das gewünschte Ergebnis?
Der moderne Weg ist mit den Klassen java.time. Die Frage und andere Antworten verwenden die problematischen alten Legacy-Date-Time-Klassen oder das Joda-Time-Projekt, die jetzt durch die java.time-Klassen ersetzt werden.
Definieren Sie ein Objekt DateTimeFormatter
mit einem Formatierungsmuster, das Ihren Daten entspricht.
Weisen Sie Locale
zu, um die menschliche Sprache für den Namen des Tages und den Namen des Monats sowie die kulturellen Normen für andere Formatierungsprobleme anzugeben.
Zuletzt führe das Parsen aus, um ein ZonedDateTime
Objekt zu erhalten.
zdt.toString (): 2008-09-26T20: 30-04: 00 [Amerika / New_York]
Sie können die Zeitzone von ZonedDateTime
anfordern, dargestellt als ZoneId
-Objekt. Sie können das ZoneId
dann abfragen, wenn Sie mehr Informationen über die Zeitzone benötigen.
Sehen Sie selbst in IdeOne.com .
Vermeiden Sie den Austausch von Datums- und Uhrzeitdaten in diesem schrecklichen Format. Gehen Sie nicht von Englisch aus, greifen Sie nicht auf Dinge wie den Namen des Tages zu und verwenden Sie niemals Pseudo-Zeitzonen wie Eastern Daylight Time
.
Für Zeitzonen: Geben Sie einen richtigen Zeitzonennamen im Format continent/region
an, z. B. America/Montreal
, Africa/Casablanca
oder Pacific/Auckland
. Verwenden Sie niemals die 3-4-Buchstaben-Abkürzung wie EST
oder IST
, da sie keine echten Zeitzonen sind, nicht standardisiert und nicht einmal eindeutig (!).
Verwenden Sie zum Serialisieren von Datums- und Uhrzeitwerten in Text nur die ISO 8601 Formate. Die java.time-Klassen verwenden diese Formate standardmäßig beim Analysieren / Erzeugen von Strings, um ihren Wert darzustellen.
Das Framework java.time ist in Java integriert 8 und später. Diese Klassen ersetzen die problematischen alten Legacy Datum-Uhrzeit-Klassen wie java.util.Date
, Calendar
, & amp; SimpleDateFormat
.
Das Joda-Time Projekt, jetzt in Wartungsmodus , rät zur Migration auf java.time.
Weitere Informationen finden Sie im Oracle-Lernprogramm . Und suchen Sie nach Stack Overflow für viele Beispiele und Erklärungen. Spezifikation ist JSR 310 .
Wo erhalten Sie die Klassen java.time?
Das Projekt ThreeTen-Extra erweitert java.time um zusätzliche Klassen. Dieses Projekt ist ein Testfeld für mögliche zukünftige Erweiterungen von java.time. Hier finden Sie einige nützliche Klassen wie Interval
, < a href="http://www.threeten.org/threeten-extra/apidocs/org/threeten/extra/YearWeek.html"> YearWeek
, YearQuarter
und mehr .