Question

    

Cette question a déjà une réponse ici:

         

Je suis en train d'analyser une date qui ressemble à ceci:

2010-04-05T17:16:00Z

Ceci est une date valide par http://www.ietf.org/rfc/rfc3339. txt . Le « Z » littérale « impliquent que UTC    est le point de référence préféré pour la durée spécifiée. "

Si je tente de l'analyser en utilisant SimpleDateFormat et ce modèle:

yyyy-MM-dd'T'HH:mm:ss

Il sera analysé comme un LUN. 5 avril 2010 17:16:00 HAE

SimpleDateFormat ne parvient pas à analyser 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 décalage horaire à utiliser sur le SimpleDateFormat pour obtenir le résultat attendu, mais je ne pense pas que cela devrait être nécessaire. Y at-il quelque chose que je suis absent? Y at-il un analyseur de date alternative?

Était-ce utile?

La solution

Dans le modèle, l'inclusion d'une composante date-heure « z » indique que le format fuseau horaire doit se conformer à la fuseau horaire général "standard", dont des exemples sont Pacific Standard Time; PST; GMT-08:00.

A 'Z' indique que le fuseau horaire est conforme à la RFC 822 fuseau horaire standard, par exemple -0800.

Je pense que vous avez besoin d'une 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());
}

Autres conseils

Java ne pas analyser correctement les dates ISO.

Tout comme la réponse de McKenzie.

Il suffit de fixer le Z avant l'analyse syntaxique.

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 analyse syntaxique est au format ISO 8601.

En java 7 le motif à lire et appliquer le suffixe de fuseau horaire doit lire yyyy-MM-dd'T'HH:mm:ssX

tl; dr

Instant.parse ( "2010-04-05T17:16:00Z" )

ISO 8601 standard

Votre chaîne est conforme à la ISO 8601 standard (dont le dit RFC 3339 est un profil).

Évitez j.u.Date

Les classes java.util.Date et .Calendar avec Java sont notoirement gênants. Évitez les.

Au lieu d'utiliser soit le bibliothèque Joda-Time ou le nouveau package java.time en Java 8. les deux utilisent ISO 8601 que leurs valeurs par défaut pour l'analyse syntaxique et de générer des représentations de chaîne de valeurs date-heure.

java.time

Le java.time cadre construit en Java 8 et évince plus tard les classes gênants vieux java.util.Date/.Calendar. Les nouvelles classes sont inspirés par le Joda-Time cadre, conçu comme son successeur, similaire dans le concept, mais re-architecturé. Défini par JSR 310 . Prolongée par le ThreeTen-Extra projet . Voir la Tutoriel.

La classe Instant dans java.time représente un moment sur la timeline dans UTC fuseau horaire.

Le Z à la fin de votre chaîne d'entrée signifie Zulu qui signifie UTC. Une telle chaîne peut être analysée directement par la classe Instant, sans avoir besoin de spécifier un formatter.

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

De là, vous pouvez appliquer un fuseau horaire ( ZoneId ) pour régler cette Instant en ZonedDateTime . Rechercher Stack Overflow pour la discussion et des exemples.

Si vous devez utiliser un java.util.Date objet, vous pouvez convertir en appelant les nouvelles méthodes de conversion ajoutés 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 de 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 );

Convertir un java.util.Date si nécessaire.

java.util.Date date = dateTime.toDate();

Selon la dernière ligne sur la date et heure modèles table des API Java 7

X Fuseau horaire ISO 8601 fuseau horaire -08; -0800; -08: 00

Pour la zone de temps ISO 8601 vous devez utiliser:

  • X pour (-08 ou Z),
  • XX pour (-0800 ou Z),
  • XXX pour (-08: 00 ou Z);

pour analyser votre « 2010-04-05T17: 16: 00Z » vous pouvez utiliser   "aaaa-MM-jj'T'HH: mm: SSX" ou "aaaa-MM-jj'T'HH: mm: ssXX" ou « aaaa-MM-jj'T'HH: 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"));

sera correctement imprimer 'Mon 5 avril 2010 13:16:00 HAE

« X » ne fonctionne que si secondes partielles ne sont pas présents: à savoir motif de SimpleDateFormat

"aaaa-MM-jj'T'HH: mm: SSX"

est correctement analyser

"2008-01-31T00: 00: 00Z"

"aaaa-MM-jj'T'HH: mm: ss.SX"

Pas d'analyser

"2008-01-31T00: 00: 00.000Z"

Triste mais vrai, une date-heure avec les secondes partielles ne semble pas être une date valide ISO: http : //en.wikipedia.org/wiki/ISO_8601

Le fuseau horaire doit être quelque chose comme « GMT + 00: 00 ». Ou 0000 afin d'être correctement analysées par le SimpleDateFormat - vous pouvez remplacer Z avec cette construction

Le projet comprend Restlet une classe InternetDateFormat qui peut analyser les dates RFC 3339.

Restlet InternetDateFormat

Bien, vous pourriez vouloir remplacer la fuite « Z » avec « UTC » avant de l'analyser.

Je donne 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-bibliothèque / java / google-api-java-client / setup # télécharger

est ici référence API,
https://developers.google.com/api-client-library/java/google-http-java-client/reference/1.20.0/com/google/api/client/util/DateTime

Le 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

tests unitaires DateTime,
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 l'heure pour Java SE 8. Ce projet est le backport Java SE 6 et 7.

Si vous travaillez sur un Android projet vous voudrez peut-être à la caisse ThreeTenABP bibliothèque .

compile "com.jakewharton.threetenabp:threetenabp:${version}"
  

JSR-310 a été inclus dans Java 8 comme java.time. * Package. Il est un remplacement complet pour les API de date et souffrants Calendrier dans Java et Android. JSR-310 a été backported à Java 6 par son créateur, Stephen Colebourne, dont cette bibliothèque est adaptée.

Sous Java 8 Utilisez le DateTimeFormatter.ISO_DATE_TIME prédéfini

 DateTimeFormatter formatter = DateTimeFormatter.ISO_DATE_TIME;
 ZonedDateTime result = ZonedDateTime.parse("2010-04-05T17:16:00Z", formatter);

Je suppose que la meilleure façon

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

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top