Java SimpleDateFormat ("aaaa-MM-jj'T'HH: mm: ss'Z '") donne le fuseau horaire comme IST

148

J'ai le constructeur SimpleDateFormat comme

SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'")

et j'analyse la chaîne "2013-09-29T18:46:19Z".

J'ai lu qu'ici Z représente le GMT/UTCfuseau horaire. mais quand j'imprime cette date sur la console, il imprime le fuseau horaire IST pour la date retournée.

Maintenant, ma question est de savoir si ma sortie est bonne ou mauvaise?

Pradip Borde
la source
3
oui c'est ce que représente «Z». Z- Fuseau horaire
Woody
5
Z = heure zoulou => GMT + 0, vous n'avez visiblement pas servi votre pays;)
MushyPeas

Réponses:

251

Vous n'avez pas défini le fuseau horaire uniquement ajouté un Zà la fin de la date / heure, donc cela ressemblera à une date / heure GMT mais cela ne change pas la valeur.

Réglez le fuseau horaire sur GMT et ce sera correct.

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
Peter Lawrey
la source
3
Si vous avez une date, dites 2012-12-06T06: 00: 00 sans le Z, cela représente-t-il GMT?
binarygiant
3
@binarygiant Vous devriez demander à ceux qui l'ont envoyé. Il peut s'agir de l'heure locale de l'expéditeur.
Peter Lawrey
2
Le fuseau horaire peut être réglé sur "UTC"
Prashanth
2
Au lieu de définir le fuseau horaire dans autant d'endroits pour différentes bibliothèques et d'éviter les conflits avec le fuseau horaire de votre ordinateur / ordinateur portable, vous devez toujours définir le fuseau horaire par défaut de la JVM en définissant la propriété système user.timezone: java -Duser.timezone = GMT ...
kisna
100

'T'et 'Z'sont considérés ici comme des constantes. Vous devez passer Zsans les guillemets. De plus, vous devez spécifier le fuseau horaire dans la chaîne d'entrée.

Exemple: 2013-09-29T18:46:19-0700 Et le format comme"yyyy-MM-dd'T'HH:mm:ssZ"

Subir Kumar Sao
la source
Subir, Merci pour votre réponse, mais qu'est-ce que "0700" ajouté à la chaîne d'entrée ??
Pradip Borde
-0700est le fuseau horaire ie -7: 00 Hrs
Subir Kumar Sao
12
pour -07: 00 heure et non -0700 ce serait le suivant: aaaa-MM-jj'T'HH: mm: ss.SSSXXX
Tastybrownies
48

De la chaîne ISO 8601 à l'objet de date Java

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
sdf.parse("2013-09-29T18:46:19Z"); //prints-> Mon Sep 30 02:46:19 CST 2013

si vous ne définissez pas, TimeZone.getTimeZone("GMT")il afficheraSun Sep 29 18:46:19 CST 2013

De l'objet de date Java à la chaîne ISO 8601

Et pour convertir un Dateobjet en ISO 8601 Standard ( yyyy-MM-dd'T'HH:mm:ss'Z'), utilisez le code suivant

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.US);
sdf.setTimeZone(TimeZone.getTimeZone("GMT"));           
System.out.println(sdf.format(new Date())); //-prints-> 2015-01-22T03:23:26Z

Notez également que sans les impressions ' 'à Zyyyy-MM-dd'T'HH:mm:ssZ2015-01-22T03:41:02+0000

AZ_
la source
2
Cela me donne java.text.ParseException: Date impossible à analyser: "2018-05-01T18: 30: 00.000Z" @AZ_
Mansuu ....
41

SI vous voulez gérer « norme » représentation JSON de la date alors préférable d'utiliser ce modèle: "yyyy-MM-dd'T'HH:mm:ssX".

Remarquez le Xà la fin. Il gérera les fuseaux horaires dans la norme ISO 8601 , et ISO 8601 est exactement ce qui produit cette déclaration en Javascriptnew Date().toJSON()

Comparé à d'autres réponses, il présente certains avantages:

  1. Vous n'avez pas besoin de demander à vos clients d'envoyer la date en GMT
  2. Vous n'avez pas besoin de convertir explicitement votre objet Date en GMT en utilisant ceci: sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
MyTitle
la source
1
J'utilise la playliaison automatique de formulaire et j'utilise l' @Format.DateTimeannotation. Utiliser le modèle par défaut avec Zà la fin semble incorrect. Après avoir changé en X, cela fonctionne. Merci beaucoup
transang le
Si votre date spécifie le fuseau horaire de manière conforme à la RFC822, telle que "-0500", cela fonctionne très bien. Mais pour une date telle que "2013-07-15T10: 22: 17-05: 00" (également valide ISO8601 TZ), cela se rompt. Dans ce cas, vous devez utiliser "aaaa-MM-jj'T'HH: mm: ssXXX".
Lambart
23

tl; dr

Les autres réponses sont obsolètes à partir de Java 8.

Instant                           // Represent a moment in UTC. 
.parse( "2013-09-29T18:46:19Z" )  // Parse text in standard ISO 8601 format where the `Z` means UTC, pronounces “Zulu”.
.atZone(                          // Adjust from UTC to a time zone. 
    ZoneId.of( "Asia/Kolkata" )
)                                 // Returns a `ZonedDateTime` object. 

ISO 8601

Le format de votre chaîne est conforme à la norme ISO 8601 . Cette norme définit des formats sensibles pour représenter diverses valeurs date-heure sous forme de texte.

java.time

Les anciennes classes java.util.Date/ .Calendaret java.text.SimpleDateFormatont été remplacées par le framework java.time intégré à Java 8 et versions ultérieures. Voir le didacticiel . Évitez les anciennes classes car elles se sont avérées mal conçues, déroutantes et gênantes.

Une partie de la mauvaise conception des anciennes classes vous a mordu, où la toStringméthode applique le fuseau horaire par défaut actuel de la JVM lors de la génération d'une représentation textuelle de la valeur date-heure qui est en fait en UTC (GMT); bien intentionné mais déroutant.

Les classes java.time utilisent les formats ISO 8601 par défaut lors de l'analyse / génération de représentations textuelles des valeurs date-heure. Donc pas besoin de spécifier un modèle d'analyse.

An Instantest un moment sur la chronologie en UTC .

Instant instant = Instant.parse( "2013-09-29T18:46:19Z" );

Vous pouvez appliquer un fuseau horaire selon vos besoins pour produire un ZonedDateTimeobjet.

ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = instant.atZone( zoneId );

Tableau des types de date-heure en Java, à la fois modernes et hérités

Basil Bourque
la source
22

et si vous n'avez pas l'option d'aller sur java8, mieux vaut utiliser 'yyyy-MM-dd'T'HH: mm: ssX XX ' car cela est correctement analysé à nouveau (alors qu'avec un seul X, cela peut ne pas être le cas. .. en fonction de votre fonction d'analyse)

X génère: +01

XXX génère: +01: 00

Thirdman
la source
0

Pour Java 8: vous pouvez utiliser intégré java.time.format.DateTimeFormatterpour réduire tout risque de fautes de frappe, comme

DateTimeFormatter formatter = DateTimeFormatter.ISO_ZONED_DATE_TIME;

ISO_ZONED_DATE_TIME représente l' 2011-12-03T10:15:30+01:00[Europe/Paris]un des formats DateTime standard fournis par le lien Oracle

Niraj
la source