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?

66
demandé sur DanInDC 2010-04-06 00:17:08

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());
}
30
répondu Paul McKenzie 2010-04-07 16:50:46

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
47
répondu Alex 2015-12-02 15:47:01

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

32
répondu Dave Patterson 2014-06-24 18:55:50

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();
19
répondu Basil Bourque 2017-05-03 21:21:11

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'

11
répondu Legna 2016-05-11 22:02:13

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

5
répondu Sandy McPherson 2015-03-23 12:23:50

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.

3
répondu Cornel Creanga 2010-04-05 20:36:09

le projet restlet comprend une classe InternetDateFormat qui peut analyser les dates de la RFC 3339.

Restlet InternetDateFormat

cependant, vous pourriez juste vouloir remplacer le 'Z' arrière par " UTC " avant de le parser.

2
répondu Marcus Adams 2010-04-05 20:57:27

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

2
répondu Johnny 2016-03-17 08:23:57

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.

2
répondu JJD 2016-03-24 14:29:46

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

0
répondu JavaBohne 2017-05-03 08:25:19

depuis java 8 Il suffit d'utiliser ZonedDateTime.parse("2010-04-05T17:16:00Z")

0
répondu Dušan Zahoranský 2017-11-06 01:12:47