J'essaie d'obtenir une conversion simple d'un fuseau horaire dans un autre en utilisant Java Date and Calendar. J'essaie d'exécuter le code suivant
Calendar instance = Calendar.getInstance(TimeZone.getTimeZone("Europe/London"));
Date date = instance.getTime();
System.out.println(date);
GregorianCalendar instance2 = new GregorianCalendar(TimeZone.getTimeZone("Europe/Athens"));
instance2.setTime(instance.getTime());
System.out.println(instance2.getTime());
mais cela renvoie toujours la même date, plutôt que +1 heure ... L'ensemble du problème semble trivial mais je ne trouve pas de réponse simple à cela. Merci d'avance pour votre aide.
Lorsque vous imprimez la date à l'aide de System.out.println(date); or System.out.println(instance2.getTime());
, le Date
renvoyé par instance2.getTime()
est TimeZone independent
et imprime toujours la date dans le fuseau horaire local.
Au lieu de cela, vous pouvez utiliser DateFormat/SimpleDateFormat
:
DateFormat formatter= new SimpleDateFormat("MM/dd/yyyy HH:mm:ss Z");
formatter.setTimeZone(TimeZone.getTimeZone("Europe/London"));
System.out.println(formatter.format(date));
formatter.setTimeZone(TimeZone.getTimeZone("Europe/Athens"));
System.out.println(formatter.format(instance2.getTime()))
La réponse acceptée est correcte. Aucun fuseau horaire n'a été attribué à la classe Java.util.Date.†, mais son implémentation toString
applique de manière confuse le fuseau horaire par défaut actuel de la JVM.
C'est l'une des nombreuses raisons pour éviter les classes Java.util.Date, .Calendar et SimpleDateFormat notoirement gênantes fournies avec Java. Évite-les. Utilisez plutôt:
Voici un exemple de code dans Joda-Time 2.3. Recherchez StackOveflow pour de nombreux autres exemples et de nombreuses discussions.
DateTimeZone timeZoneLondon = DateTimeZone.forID( "Europe/London" );
DateTimeZone timeZoneAthens = DateTimeZone.forID( "Europe/Athens" );
DateTime nowLondon = DateTime.now( timeZoneLondon );
DateTime nowAthens = nowLondon.withZone( timeZoneAthens );
DateTime nowUtc = nowLondon.withZone( DateTimeZone.UTC );
Java 8 et versions ultérieures ont un nouveau package Java.time intégré. Ce package a été inspiré par Joda-Time. Bien qu'ils partagent des similitudes et des noms de classe, ils sont différents; chacun a des caractéristiques que l'autre manque. Une différence notable est que Java.time évite les constructeurs, utilise à la place des méthodes d'instanciation statiques.
Dans le cas de cette Question, ils fonctionnent de la même manière. Spécifiez un fuseau horaire et appelez une méthode now
pour obtenir l'instant actuel, puis créez une nouvelle instance basée sur l'ancienne instance immuable pour ajuster le fuseau horaire.
Notez les deux classes de fuseau horaire différentes. L'un est un fuseau horaire nommé comprenant toutes les règles de l'heure d'été et d'autres anomalies de ce type, plus un décalage par rapport à l'UTC, tandis que l'autre n'est que le décalage.
ZoneId zoneMontréal = ZoneId.of("America/Montreal");
ZonedDateTime nowMontréal = ZonedDateTime.now ( zoneMontréal );
ZoneId zoneTokyo = ZoneId.of("Asia/Tokyo");
ZonedDateTime nowTokyo = nowMontréal.withZoneSameInstant( zoneTokyo );
ZonedDateTime nowUtc = nowMontréal.withZoneSameInstant( ZoneOffset.UTC );
†En fait, le Java.util.Date
classe a un fuseau horaire enfoui dans son code source . Mais la classe ignore ce fuseau horaire à des fins plus pratiques. Donc, en sténographie, on dit souvent que j.u.Date n'a pas de fuseau horaire attribué. Déroutant? Oui. Évitez le désordre qui est j.u.Date et optez pour Joda-Time et/ou Java.time.
Vous pouvez utiliser l'extrait de code suivant
String dateString = "14 Jul 2014 00:11:04 CEST";
date = formatter.parse(dateString);
System.out.println(formatter.format(date));
// Set the formatter to use a different timezone - Indochina Time
formatter.setTimeZone(TimeZone.getTimeZone("Asia/Bangkok"));
System.out.println("ICT time : "+formatter.format(date));