205 votes

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

J'ai le constructeur SimpleDateFormat comme

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

et je suis en train d'analyser la chaîne "2013-09-29T18:46:19Z".

J'ai lu que ici Z représente le fuseau horaire GMT/UTC. mais lorsque j'imprime cette date sur la console, elle affiche le fuseau horaire IST pour la date retournée.

Maintenant ma question est de savoir si ma sortie est correcte ou incorrecte?

330voto

Peter Lawrey Points 229686

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

Définissez 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"));

121voto

Subir Kumar Sao Points 4080

'T' et 'Z' sont considérés ici comme des constantes. Vous devez passer Z sans 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"

63voto

AZ_ Points 7127

De la chaîne ISO 8601 à l'objet 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"); //affiche-> Lun Sep 30 02:46:19 CST 2013

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

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

Et pour convertir l'objet Date en Norme ISO 8601 (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())); //-affiche-> 2015-01-22T03:23:26Z

Notez également que sans les ' ' à Z yyyy-MM-dd'T'HH:mm:ssZ affiche 2015-01-22T03:41:02+0000

53voto

MyTitle Points 1005

SI vous souhaitez manipuler la représentation JSON 'standard' de la date, il vaut mieux utiliser ce motif : "yyyy-MM-dd'T'HH:mm:ssX".

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

Comparé à d'autres réponses, cela présente quelques avantages :

  1. Vous n'avez pas besoin d'exiger que vos clients envoient 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"));

39voto

Basil Bourque Points 8938

Tl;dr

Les autres réponses sont dépassées à partir de Java 8.

Instant                           // Représente un moment en UTC.
.parse( "2013-09-29T18:46:19Z" )  // Analyse du texte au format ISO 8601 standard où le `Z` signifie UTC, prononcé "Zulu".
.atZone(                          // Ajuster de l'UTC à un fuseau horaire.
    ZoneId.of( "Asia/Kolkata" )
)                                 // Renvoie un objet `ZonedDateTime`.

ISO 8601

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

java.time

Les anciennes classes java.util.Date/.Calendar et java.text.SimpleDateFormat ont été remplacées par le framework java.time intégré à Java 8 et ultérieur. Voir Tutoriel. Évitez les anciennes classes car elles se sont avérées mal conçues, confuses et problématiques.

Une partie de la mauvaise conception des anciennes classes vous a affecté, où la méthode toString applique le fuseau horaire par défaut actuel du JVM lors de la génération d'une représentation textuelle de la valeur de date-heure qui est en réalité 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 de date-heure. Il n'est donc pas nécessaire de spécifier un motif d'analyse.

Un Instant est un moment sur la ligne de temps en UTC.

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

Vous pouvez appliquer un fuseau horaire au besoin pour produire un objet ZonedDateTime.

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X