web-dev-qa-db-fra.com

Convertir la date en un fuseau horaire différent

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.

24
Bober02

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()))
37
Yogendra Singh

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.

Évitez Java.util.Date et .Calendar

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:

Joda-Time

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.time

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.

15
Basil Bourque

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));
3
Srijani Ghosh