simpledateformat analyse date avec 'Z' littéral [dupliquer]
cette question a déjà une réponse ici:
- conversion de chaîne conforme à la norme ISO 8601 en java.util.Date 25 réponses
je suis en train 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 " Z "littéral" implique que UTC est le point de référence préféré pour la durée spécifiée."
si j'essaie de l'analyser en utilisant SimpleDateFormat et ce modèle:
yyyy-MM-dd'T'HH:mm:ss
Il va être analysé comme un Lun Avr 05 17:16:00 EDT 2010
SimpleDateFormat est incapable de parser la chaîne avec ces motifs:
yyyy-MM-dd'T'HH:mm:ssz
yyyy-MM-dd'T'HH:mm:ssZ
je peux définir explicitement le fuseau horaire utiliser sur le formulaire Simpledate pour obtenir le résultat attendu, mais je ne pense pas que cela devrait être nécessaire. Est-il quelque chose que je suis absent? Y a-t-il un autre analyseur de date?
12 réponses
dans le schéma, l'inclusion d'une composante date-heure" z "indique que le format du fuseau horaire doit être conforme au fuseau horaire général " standard", dont les exemples sont Pacific Standard Time; PST; GMT-08:00
.
A 'Z' indique que le fuseau horaire est conforme à la norme RFC 822 , p.ex. -0800
.
je pense que vous avez besoin d'un convertisseur de type de données ...
@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 ne traite pas correctement les dates ISO.
semblable à la réponse de McKenzie.
il suffit de fixer le Z
avant parsing.
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.
en java 7 le modèle pour lire et appliquer le suffixe de fuseau horaire doit se lire yyyy-MM-dd'T'HH:mm:ssX
tl; dr
Instant.parse ( "2010-04-05T17:16:00Z" )
norme ISO 8601
votre chaîne est conforme à la norme ISO 8601 (dont le mentionné RFC 3339 est un profil).
eviter J. U. Date
La java.util.La Date et l' .Les classes de calendrier empaquetées avec Java sont notoirement pénibles. Les éviter.
au lieu d'utiliser l'un ou l'autre Joda-Time bibliothèque ou le java.package en Java 8. Les deux utilisent ISO 8601 comme valeur par défaut pour l'analyse et la génération de représentations de chaîne de caractères des valeurs date-heure.
de java.time
Le de java.time framework construit dans Java 8 et plus tard supplante le vieux java gênant.util.Date./Calendrier des classes. Les nouvelles classes sont inspirées par le très réussi Joda-Time cadre, conçu comme son successeur, similaire dans le concept mais restructuré. Défini par JSR 310 . Prolongé par le projet ThreeTen-Extra . Voir le tutoriel .
la classe Instant
en java.le temps représente un moment sur la ligne du temps dans le fuseau horaire UTC .
le Z
à la fin de votre chaîne de saisie signifie Zulu
qui est pour UTC
. Une telle chaîne peut être directement analysée par la classe Instant
, sans qu'il soit nécessaire de spécifier un formatteur.
String input = "2010-04-05T17:16:00Z";
Instant instant = Instant.parse ( input );
Dump à console.
System.out.println ( "instant: " + instant );
instant: 2010-04-05T17: 16 :00Z
de là, vous pouvez appliquer un fuseau horaire( ZoneId
) pour ajuster ce Instant
dans un ZonedDateTime
. Rechercher le débordement de la pile pour une discussion et des 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 );
Joda-Time
exemple dans Joda-Time 2.5.
DateTimeZone timeZone = DateTimeZone.forID( "Europe/Paris" ):
DateTime dateTime = new DateTime( "2010-04-05T17:16:00Z", timeZone );
Convertissez-vous en UTC.
DateTime dateTimeUtc = dateTime.withZone( DateTimeZone.UTC );
Convertissez-vous en java.util.La Date si nécessaire.
java.util.Date date = dateTime.toDate();
selon la dernière ligne de la Date and Time Patterns table de la Java 7 API
x fuseau horaire ISO 8601 fuseau horaire -08; -0800; -08: 00
pour le fuseau horaire ISO 8601, vous devez utiliser X( -08 ou Z); XX (-0800 ou Z); et XXX (-08:00 ou Z) pour analyser votre "2010-04-05T17: 16:00Z" est soit "AAAA-MM-jj'T'HH: mm: ssX" ou "AAAA-MM-jj'T'HH: mm: ssXX" ou "AAAA-MM-jj'T'HH:mm:ssXXX" devrait fonctionner.
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"));
correctement impression "Lun Avr 05 à 13:16:00 EDT 2010'
le "X" ne fonctionne qu'en l'absence de secondes partielles: c'est-à-dire en L'absence de forme simple de
"AAAA-MM-jj'T'HH: mm: ssX "
Va analyser correctement
"2008-01-31T00: 00:00Z"
mais
" AAAA-MM-jj'T'HH:mm:SS.SX "
ne Sera PAS analyser
"2008-01-31T00: 00:00.000 Z"
triste mais vrai, une date-heure avec partielle secondes 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 afin d'être correctement interprété par le SimpleDateFormat - vous pouvez remplacer Z par cette construction.
le projet restlet comprend une classe InternetDateFormat qui peut analyser les dates de la RFC 3339.
cependant, vous pourriez juste vouloir remplacer le 'Z' arrière par " UTC " avant de le parser.
je fournis une autre réponse que j'ai trouvé 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 la classe DateTime
,
https://github.com/google/google-http-java-client/blob/master/google-http-client/src/main/java/com/google/api/client/util/DateTime.java
DateTime
essais 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 d'heure pour Java SE 8. Ce projet est le backport vers Java SE 6 et 7.
dans le cas où vous travaillez sur un Android projet, vous pourriez vouloir consulter le Bibliothèque ThreeTenABP .
compile "com.jakewharton.threetenabp:threetenabp:${version}"
JSR-310 a été inclus dans Java 8 sous le nom de java.temps.* paquet. Il s'agit d'un remplacement complet pour la date de malaise et le calendrier API dans les deux Java et Android. JSR-310 a été rétroporté à Java 6 par son créateur, Stephen Colebourne, à partir duquel cette bibliothèque est adaptée.
sous Java 8 utilisez le DateTimeFormatter prédéfini.ISO_DATE_TIME
DateTimeFormatter formatter = DateTimeFormatter.ISO_DATE_TIME;
ZonedDateTime result = ZonedDateTime.parse("2010-04-05T17:16:00Z", formatter);
je suppose que c'est la manière la plus facile
depuis java 8 Il suffit d'utiliser ZonedDateTime.parse("2010-04-05T17:16:00Z")