Ich versuche ein Datum zu analysieren, das so aussieht:
2010-04-05T17:16:00Z
Dies ist ein gültiges Datum gemäß http://www.ietf.org/rfc/rfc3339.txt . Das Z-Literal "impliziert, dass UTC Der bevorzugte Bezugspunkt für die angegebene Zeit ist."
Wenn ich versuche, es mit SimpleDateFormat und diesem Muster zu analysieren:
yyyy-MM-dd'T'HH:mm:ss
Es wird als Mo Apr 05 17:16:00 EDT 2010 analysiert
SimpleDateFormat kann die Zeichenfolge nicht mit den folgenden Mustern analysieren:
yyyy-MM-dd'T'HH:mm:ssz
yyyy-MM-dd'T'HH:mm:ssZ
Ich kann die TimeZone explizit so einstellen, dass sie im SimpleDateFormat verwendet wird, um die erwartete Ausgabe zu erhalten, aber ich denke nicht, dass dies notwendig sein sollte. Fehlt mir etwas? Gibt es einen alternativen Datums-Parser?
In dem Muster zeigt die Einbeziehung einer 'z'-Datum/Uhrzeit-Komponente an, dass das Zeitzonenformat der Allgemeinen Zeitzone "Standard" entsprechen muss. Beispiele hierfür sind Pacific Standard Time; PST; GMT-08:00
.
Ein "Z" zeigt an, dass die Zeitzone der RFC 822-Zeitzone Standard entspricht, z. -0800
.
Ich denke du brauchst einen DatatypeConverter ...
@Test
public void testTimezoneIsGreenwichMeanTime() throws ParseException {
final Calendar calendar = javax.xml.bind.DatatypeConverter.parseDateTime("2010-04-05T17:16:00Z");
TestCase.assertEquals("gotten timezone", "GMT+00:00", calendar.getTimeZone().getID());
}
ISO analysiert Datumsangaben nicht korrekt.
Ähnlich wie McKenzies Antwort.
Fixiere einfach die Z
vor der Analyse.
Code
String string = "2013-03-05T18:05:05.000Z";
String defaultTimezone = TimeZone.getDefault().getID();
Date date = (new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ")).parse(string.replaceAll("Z$", "+0000"));
System.out.println("string: " + string);
System.out.println("defaultTimezone: " + defaultTimezone);
System.out.println("date: " + (new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ")).format(date));
Ergebnis
string: 2013-03-05T18:05:05.000Z
defaultTimezone: America/New_York
date: 2013-03-05T13:05:05.000-0500
Das Datum, das Sie analysieren, hat das ISO8601-Format.
In Java 7 sollte das Muster zum Lesen und Anwenden des Zeitzonen-Suffixes yyyy-MM-dd'T'HH:mm:ssX
lauten.
Instant.parse ( "2010-04-05T17:16:00Z" )
Ihr String entspricht der Norm ISO 8601 (von der der angegebene RFC 3339 ein Profil ist).
Die mit Java gebündelten Klassen Java.util.Date und .Calendar sind notorisch lästig. Vermeide sie.
Verwenden Sie stattdessen entweder die Bibliothek Joda-Time oder das neue Java.time-Paket in Java 8. Beide verwenden ISO 8601 als Standardeinstellungen für das Analysieren und Generieren von Zeichenfolgendarstellungen von Datums-/Zeitwerten.
Das Java.time - Framework, das in Java 8 und später integriert ist, ersetzt die problematischen alten Java.util.Date/.Calendar-Klassen. Die neuen Klassen sind von dem sehr erfolgreichen Joda-Time - Framework inspiriert, das als Nachfolger gedacht ist und im Konzept ähnlich ist, aber neu konzipiert wurde. Definiert durch JSR 310 . Erweitert um das ThreeTen-Extra Projekt. Siehe das Tutorial .
Die Instant
-Klasse in Java.time repräsentiert einen Moment auf der Zeitleiste in der Zeitzone UTC .
Die Variable Z
am Ende Ihrer Eingabezeichenfolge bedeutet Zulu
, die für UTC
steht. Eine solche Zeichenfolge kann direkt von der Instant
-Klasse analysiert werden, ohne dass ein Formatierer angegeben werden muss.
String input = "2010-04-05T17:16:00Z";
Instant instant = Instant.parse ( input );
Auf die Konsole ausgeben.
System.out.println ( "instant: " + instant );
augenblick: 2010-04-05T17: 16: 00Z
Von dort aus können Sie eine Zeitzone ( ZoneId
) anwenden, um diese Instant
in eine ZonedDateTime
anzupassen. Durchsuchen Sie den Stack Overflow für Diskussionen und Beispiele.
Wenn Sie ein Java.util.Date
- Objekt verwenden müssen, können Sie die Konvertierung durchführen, indem Sie die neuen Konvertierungsmethoden aufrufen, die den alten Klassen hinzugefügt wurden, z. B. die statische Methode Java.util.Date.from( Instant )
.
Java.util.Date date = Java.util.Date.from( instant );
Beispiel in Joda-Time 2.5.
DateTimeZone timeZone = DateTimeZone.forID( "Europe/Paris" ):
DateTime dateTime = new DateTime( "2010-04-05T17:16:00Z", timeZone );
Konvertieren Sie in UTC.
DateTime dateTimeUtc = dateTime.withZone( DateTimeZone.UTC );
Konvertieren Sie bei Bedarf in ein Java.util.Date.
Java.util.Date date = dateTime.toDate();
Gemäß der letzten Zeile in der Tabelle Datums- und Zeitmuster der Java 7-API
X Zeitzone ISO 8601 Zeitzone -08; -0800; -08: 00
Für die ISO 8601-Zeitzone sollten Sie Folgendes verwenden:
um Ihr "2010-04-05T17: 16: 00Z" zu analysieren, können Sie entweder "yyyy-MM-dd'T'HH: mm: ssX" oder "yyyy-MM-dd'T'HH: mm: ssXX") ssXXX ".
System.out.println(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssX").parse("2010-04-05T17:16:00Z"));
System.out.println(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXX").parse("2010-04-05T17:16:00Z"));
System.out.println(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX").parse("2010-04-05T17:16:00Z"));
wird 'Mo Apr 05 13:16:00 EDT 2010' korrekt ausdrucken
Das 'X' funktioniert nur, wenn keine Sekunden vorhanden sind: SimpleDateFormat-Muster von
"JJJJ-MM-dd'T'HH: mm: ssX"
Wird richtig analysieren
"2008-01-31T00: 00: 00Z"
aber
"JJJJ-MM-dd'T'HH: mm: ss.SX"
Wird NICHT analysiert
"2008-01-31T00: 00: 00.000Z"
Traurig, aber wahr, ein Datum/Uhrzeit mit Sekunden in Sekunden scheint kein gültiges ISO-Datum zu sein: http://en.wikipedia.org/wiki/ISO_8601
Die Zeitzone sollte etwa "GMT + 00: 00" oder 0000 sein, um vom SimpleDateFormat richtig analysiert zu werden. Sie können Z durch diese Konstruktion ersetzen.
Ich gebe eine weitere Antwort, die ich mit api-client-library
von Google gefunden habe
try {
DateTime dateTime = DateTime.parseRfc3339(date);
dateTime = new DateTime(new Date(dateTime.getValue()), TimeZone.getDefault());
long timestamp = dateTime.getValue(); // get date in timestamp
int timeZone = dateTime.getTimeZoneShift(); // get timezone offset
} catch (NumberFormatException e) {
e.printStackTrace();
}
Installationsanleitung,
https://developers.google.com/api-client-library/Java/google-api-Java-client/setup#download
Hier ist eine API-Referenz,
https://developers.google.com/api-client-library/Java/google-http-Java-client/reference/1.20.0/com/google/api/client/util/DateTime
Quellcode von DateTime
Class,
https://github.com/google/google-http-Java-client/blob/master/google-http-client/src/main/Java/com/google/api/client/util/DateTime .Java
DateTime
Unit-Tests,
https://github.com/google/google-http-Java-client/blob/master/google-http-client/src/test/Java/com/google/api/client/util/DateTimeTest .Java # L121
In Bezug auf JSR-310 könnte ein anderes Projekt von Interesse sein threetenbp .
JSR-310 bietet eine neue Datums- und Zeitbibliothek für Java SE 8. Dieses Projekt ist der Rückport auf Java SE 6 und 7.
Wenn Sie an einem Android - Projekt arbeiten, können Sie die ThreeTenABP-Bibliothek überprüfen.
compile "com.jakewharton.threetenabp:threetenabp:${version}"
JSR-310 wurde in Java 8 als Java.time. * -Paket enthalten. Es ist ein vollständiger Ersatz für die angeschlagenen Datums- und Kalender-APIs in Java und Android. JSR-310 wurde von seinem Ersteller Stephen Colebourne nach Java 6 zurückportiert, von dem diese Bibliothek angepasst wurde.
Das Restletprojekt enthält eine InternetDateFormat-Klasse, mit der RFC 3339-Daten analysiert werden können.
Möglicherweise möchten Sie jedoch nur das abschließende 'Z' durch "UTC" ersetzen, bevor Sie es analysieren.
Verwenden Sie unter Java 8 das vordefinierte DateTimeFormatter.ISO_DATE_TIME
DateTimeFormatter formatter = DateTimeFormatter.ISO_DATE_TIME;
ZonedDateTime result = ZonedDateTime.parse("2010-04-05T17:16:00Z", formatter);
Ich denke, es ist der einfachste Weg
Seit Java 8 verwenden Sie einfach ZonedDateTime.parse("2010-04-05T17:16:00Z")