J'essaie d'analyser une date qui ressemble à ceci:
2010-04-05T17:16:00Z
C'est une date valide par http://www.ietf.org/rfc/rfc3339.txt . Le littéral "Z" "implique que UTC Est le point de référence préféré pour l'heure spécifiée".
Si j'essaye de l'analyser en utilisant SimpleDateFormat et ce modèle:
yyyy-MM-dd'T'HH:mm:ss
Il sera analysé comme un lun. 05 avr. 17:16:00 EDT 2010
SimpleDateFormat est incapable d'analyser la chaîne avec ces modèles:
yyyy-MM-dd'T'HH:mm:ssz
yyyy-MM-dd'T'HH:mm:ssZ
Je peux explicitement configurer TimeZone à utiliser sur SimpleDateFormat pour obtenir le résultat attendu, mais je ne pense pas que cela devrait être nécessaire. Y a-t-il quelque chose qui me manque? Existe-t-il un autre analyseur de date?
Dans le modèle, l'inclusion d'un composant date-heure 'z' indique que le format du fuseau horaire doit être conforme au fuseau horaire Général "standard", les exemples étant Pacific Standard Time; PST; GMT-08:00
.
Un «Z» indique que le fuseau horaire est conforme à la norme de fuseau horaire RFC 822 , par ex. -0800
.
Je pense que vous avez besoin d'un 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());
}
Java n'analyse pas correctement les dates ISO.
Semblable à la réponse de McKenzie.
Il suffit de corriger la Z
avant d'analyser.
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));
Résultat
string: 2013-03-05T18:05:05.000Z
defaultTimezone: America/New_York
date: 2013-03-05T13:05:05.000-0500
La date que vous analysez est au format ISO8601.
Dans Java 7, le modèle à utiliser pour lire et appliquer le suffixe de fuseau horaire doit indiquer yyyy-MM-dd'T'HH:mm:ssX
Instant.parse ( "2010-04-05T17:16:00Z" )
Votre chaîne est conforme à la norme ISO 8601 (la RFC 3339 mentionnée étant un profil).
Les classes Java.util.Date et .Calendar fournies avec Java sont notoirement gênantes. Évite-les.
Utilisez plutôt la bibliothèque Joda-Time ou le nouveau package Java.time dans Java 8. Ils utilisent tous deux ISO 8601 par défaut pour analyser et générer des représentations sous forme de chaîne des valeurs date-heure.
La structure Java.time intégrée à Java 8 et versions ultérieures supplante les anciennes classes problématiques Java.util.Date/.Calendar. Les nouvelles classes s’inspirent du très réussi framework Joda-Time , destiné à lui succéder, de concept similaire mais de nouvelle architecture. Défini par JSR 310 . Etendu par le projet ThreeTen-Extra . Voir le Tutorial .
La classe Instant
dans Java.time représente un moment sur le scénario dans le fuseau horaire UTC .
La Z
à la fin de votre chaîne de saisie signifie Zulu
qui signifie UTC
. Une telle chaîne peut être directement analysée par la classe Instant
, sans qu'il soit nécessaire de spécifier un formateur.
String input = "2010-04-05T17:16:00Z";
Instant instant = Instant.parse ( input );
Dump à la console.
System.out.println ( "instant: " + instant );
instant: 2010-04-05T17: 16: 00Z
À partir de là, vous pouvez appliquer un fuseau horaire ( ZoneId
) pour ajuster cette Instant
en une ZonedDateTime
. Recherchez Stack Overflow pour discussion et exemples.
Si vous devez utiliser un objet Java.util.Date
, vous pouvez convertir en appelant les nouvelles méthodes de conversion ajoutées aux anciennes classes telles que la méthode statique Java.util.Date.from( Instant )
.
Java.util.Date date = Java.util.Date.from( instant );
Exemple dans Joda-Time 2.5.
DateTimeZone timeZone = DateTimeZone.forID( "Europe/Paris" ):
DateTime dateTime = new DateTime( "2010-04-05T17:16:00Z", timeZone );
Convertir en UTC.
DateTime dateTimeUtc = dateTime.withZone( DateTimeZone.UTC );
Convertissez-le en Java.util.Date si nécessaire.
Java.util.Date date = dateTime.toDate();
Selon la dernière ligne de la table MODÈLES DE DATE ET D'HEURE de la API Java 7
X Fuseau horaire ISO 8601 fuseau horaire -08; -0800; -08: 00
Pour le fuseau horaire ISO 8601, vous devez utiliser:
donc pour analyser votre "2010-04-05T17: 16: 00Z", vous pouvez utiliser l'un ou l'autre "aaaa-MM-dd'T'HH: mm: ssX" ou "aaaa-MM-dd'T'HH: mm: ssXX" ou "yyyy-MM-dd'T'H: mm: 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"));
imprimera correctement 'Mon Apr 05 13:16:00 EDT 2010'
Le 'X' ne fonctionne que si des secondes partielles ne sont pas présentes: c'est-à-dire le modèle SimpleDateFormat de
"aaaa-MM-jj'HH: mm: ssX"
Va correctement analyser
"2008-01-31T00: 00: 00Z"
mais
"aaaa-MM-jj'H'HH: mm: ss.SX"
Ne pas analyser
"2008-01-31T00: 00: 00.000Z"
Triste mais vrai, une date-heure avec des secondes partielles ne semble pas être une date ISO valide: http://en.wikipedia.org/wiki/ISO_8601
Le fuseau horaire doit être quelque chose comme "GMT + 00: 00" ou 0000 pour être correctement analysé par SimpleDateFormat - vous pouvez remplacer Z par cette construction.
Je fournis une autre réponse trouvée par api-client-library
par Google
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();
}
Guide d'installation,
https://developers.google.com/api-client-library/Java/google-api-Java-client/setup#download
Voici la référence de l'API,
https://developers.google.com/api-client-library/Java/google-http-Java-client/reference/1.20.0/com/google/api/client/util/DateTime
Code source de 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
tests unitaires,
https://github.com/google/google-http-Java-client/blob/master/google-http-client/src/test/Java/com/google/api/client/util/DateTimeTest .Java # L121
En ce qui concerne JSR-310, un autre projet d’intérêt pourrait être threetenbp .
JSR-310 fournit une nouvelle bibliothèque de date et heure pour Java SE 8. Ce projet est le port de retour pour Java SE 6 et 7.
Si vous travaillez sur un projet Android, vous pouvez extraire la librairie ThreeTenABP .
compile "com.jakewharton.threetenabp:threetenabp:${version}"
JSR-310 était inclus dans Java 8 en tant que package Java.time. *. Il remplace complètement les API de date et de calendrier défaillantes sous Java et Android. JSR-310 a été rétroporté sur Java 6 par son créateur, Stephen Colebourne, à partir duquel cette bibliothèque est adaptée.
Le projet restlet comprend une classe InternetDateFormat capable d'analyser les dates RFC 3339.
Cependant, vous voudrez peut-être simplement remplacer le «Z» final par «UTC» avant de l’analyser.
Sous Java 8, utilisez le paramètre prédéfini DateTimeFormatter.ISO_DATE_TIME.
DateTimeFormatter formatter = DateTimeFormatter.ISO_DATE_TIME;
ZonedDateTime result = ZonedDateTime.parse("2010-04-05T17:16:00Z", formatter);
Je suppose que c'est le moyen le plus simple
Depuis Java 8, utilisez simplement ZonedDateTime.parse("2010-04-05T17:16:00Z")