IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Java Discussion :

[TimeZone] Gestion des fuseaux horaires


Sujet :

Java

  1. #1
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    802
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 802
    Points : 653
    Points
    653
    Par défaut [TimeZone] Gestion des fuseaux horaires
    Je ne me suis jamais vraiment penché sur la gestion des fuseaux horaires en Java. Or j'ai maintenant un petit souci. Je n'arrive tout simplement pas à obtenir l'heure correspondant à un fuseau horaire quelconque.

    Par exemple, j'exécute ceci en local :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    Calendar cal = Calendar.getInstance();
    cal.setTimeZone(TimeZone.getTimeZone("America/New_York"));
    Date maintenant = cal.getTime();
     
    System.out.println(DateUtils.toString(maintenant, new SimpleDateFormat("dd/MM/yyyy HH:mm")));
    J'obtiens l'heure locale au lieu de celle de New York.

    J'ai un peu cherché sur Internet et il semble que TimeZone doive être utilisé avec SimpleDateFormat, mais ça me parait complètement aberrant !! Et de toute façon j'ai aussi essayé et ça ne marche pas mieux :/

    Comment fait-on pour tout simplement obtenir l'heure actuelle correspondant à un fuseau horaire quelconque ?

  2. #2
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    802
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 802
    Points : 653
    Points
    653
    Par défaut
    Bon en fait j'ai posté mon message trop tôt car en continuant de chercher j'ai trouvé la réponse :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    Calendar cal = Calendar.getInstance();
    TimeZone tz = TimeZone.getTimeZone("America/New_York");
    int offset = tz.getOffset(cal.getTimeInMillis());
    cal.add(Calendar.MILLISECOND, offset);

  3. #3
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    802
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 802
    Points : 653
    Points
    653
    Par défaut
    Je croyais avoir complètement résolut le problème, mais en essayant ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    Calendar cal = Calendar.getInstance();
    TimeZone tz = TimeZone.getTimeZone("Europe/Paris");
    int offset = tz.getOffset(cal.getTimeInMillis());
    cal.add(Calendar.MILLISECOND, offset);
     
    Date maintenant = cal.getTime();
    Je n'obtiens pas tout à fait l'heure exacte. Il semble que l'heure obtenue corresponde plutôt à l'heure d'été :/

    Comment cela se fait-il ? Je tourne avec un JDK 1.6.

  4. #4
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 563
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 563
    Points : 21 627
    Points
    21 627
    Par défaut
    Citation Envoyé par verbose Voir le message
    Comment cela se fait-il ?
    Parce que getOffset() ne peut pas gérer les heures d'été ou d'hiver, puisqu'il ne sait pas si tu lui demandes pour l'heure d'été ou l'heure d'hiver.
    C'est pas comme ça qu'on fait. C'est vraiment à SimpleDateFormat qu'il faut filer une TimeZone.

    Citation Envoyé par verbose Voir le message
    J'ai un peu cherché sur Internet et il semble que TimeZone doive être utilisé avec SimpleDateFormat, mais ça me parait complètement aberrant !!
    C'est pourtant logique. Un instant dans le temps c'est un instant dans le temps. C'est le même qu'on soit à Paris, à New York, en Chine ou sur la Lune.

    Là où les différences apparaissent, c'est quand on commence à écrire ou prononcer ces instants dans le temps. Nous on dira qu'il est 21h, l'anglais qu'il est 20h, le new yorkais qu'il est 15h, et le lunien je sais pas. Mais ils parlent tous du même instant.
    Écrire ou prononcer l'heure, c'est le problème du SimpleDateFormat, donc c'est bien lui que la TimeZone intéresse.

    Citation Envoyé par verbose Voir le message
    Et de toute façon j'ai aussi essayé et ça ne marche pas mieux :/
    Si, mais encore faut-il le faire logiquement. Faire n'importe quoi tout en s'arrangeant pour qu'il y ait un SimpleDateFormat et un TimeZone dans l'histoire, ça ne suffit pas.
    Montre le code.

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    394
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2008
    Messages : 394
    Points : 639
    Points
    639
    Par défaut
    Bonjour,

    Si tu veux convertir un Calendar en String dans la timeZone du calendar tu peux utiliser la fonction suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
     
        /**
         * Converti un Calendar en String au format spécifié, dans la timeZone du calendar
         * 
         * @param calendar Calendar à convertir
         * @param format Format dans lequel on veut convertir le Calendar
         * @return la date au format String, ou null si calendar = null;
         */
        public static String convertirCalendarEnString(Calendar calendar, String format)
        {
            String dateFormatee = null;
     
            if (calendar != null)
            {
                SimpleDateFormat formater = new SimpleDateFormat(format, Locale.FRANCE);
                formater.setTimeZone(calendar.getTimeZone());
                dateFormatee = formater.format(calendar.getTime());
            }
     
            return dateFormatee;
        }
    Romain.

  6. #6
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    802
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 802
    Points : 653
    Points
    653
    Par défaut
    Merci pour vos réponses les gars.

    Je ne suis pas d'accord avec toi thelvin, un instant t est effectivement le même dans l'absolu, mais pas en relatif. Hors le constructeur de Calendar prend un TimeZone en paramètre, ce qui laisse penser que le Calendar représente un calendrier dans un référentiel relatif au fuseau horaire.

    De fait, en local, j'obtiens l'heure d'été alors qu'on est en hiver, mais sur mon serveur hébergé aux US, j'obtiens bien l'heure d'hiver à Paris.

    Je ne comprends pas d'où vient cette particularité, liée semble-t-il à l'exécution en local.

  7. #7
    Membre confirmé
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    394
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2008
    Messages : 394
    Points : 639
    Points
    639
    Par défaut
    Par défaut SimpleDateFormat formate une date dans la TimeZone par défaut du système et non pas dans la TimeZone de ton Calendar.

    Tu peux modifier la TimeZone par défaut de ton système avec la fonction suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    TimeZone.setDefault(TimeZone zone)
    Ainsi SimpleDateFormat formatera tous tes calendar dans la timeZone que tu passeras en paramètre de cette fonction.

    Romain.

  8. #8
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 563
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 563
    Points : 21 627
    Points
    21 627
    Par défaut
    Citation Envoyé par verbose Voir le message
    Je ne suis pas d'accord avec toi thelvin,
    C'est bien, mais étant donné notre claire différence d'expérience, ça ne devrait pas te dédouaner de faire ce que je dis. J'ai dit : c'est à SimpleDateFormat qu'il faut donner une time zone. Fais ça, et si ça marche pas montre le code.

    Citation Envoyé par verbose Voir le message
    un instant t est effectivement le même dans l'absolu, mais pas en relatif. Hors le constructeur de Calendar prend un TimeZone en paramètre, ce qui laisse penser que le Calendar représente un calendrier dans un référentiel relatif au fuseau horaire.
    En effet. Ce n'est pas pour rien si un Calendar est capable de prendre une TimeZone, c'est pas pour faire joli.
    De même qu'un SimpleDateFormat écrit une heure et a donc besoin d'une TimeZone pour savoir pour quelle ville il doit l'écrire, un programmeur peut écrire une heure dans un Calendar et le Calendar a donc besoin de savoir pour quelle ville on lui donne cette heure.
    Très bien, mais ça ne te concerne absolument pas.

    En effet, si tu demandais par exemple "21h à Paris" ou "21h à New York", ça te donnerait des dates différentes, parce que c'est pas la même chose.

    C'est pas ce que tu as fait. Toi tu as demandé "maintenant à Paris" et "maintenant à New York." Ce qui est exactement le même instant.
    Un Calendrier n'a rien à voir avec ce que tu veux faire. Il ne te sert donc à rien.

    Citation Envoyé par verbose Voir le message
    Je ne comprends pas d'où vient cette particularité, liée semble-t-il à l'exécution en local.
    Tu obtiens juste des décalages de n'importe quoi qui, au final, ont l'air d'être des erreurs d'alignement heure d'été/heure d'hiver. Non, c'est juste que c'est n'importe quoi, à pas beaucoup d'heures près.

  9. #9
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    802
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 802
    Points : 653
    Points
    653
    Par défaut
    J'ai refais le test avec SimpleDateFormat, et ça marche effectivement, c'est juste que je ne m'y prenais pas bien car je n'avais pas bien compris l'esprit.

    Cela dit, je considère toujours qu'il est légitime de vouloir savoir quelle heure il est dans un fuseau horaire quelconque, et cela pas seulement dans le but de vouloir afficher cette heure. Dans mon cas je veux conserver un timestamp dans le fuseau Europe/Paris. Je veux une valeur numérique et non une String.

    Le code que j'ai publié dans mon deuxième post marche très bien sur mon serveur hébergé aux US et donc ça me suffit. Mais du coup, je me demande si je ne détourne pas l'esprit dans lequel doit être utilisé Calendar compte tenu de ce que vous m'avez dit.

  10. #10
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 563
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 563
    Points : 21 627
    Points
    21 627
    Par défaut
    Citation Envoyé par verbose Voir le message
    Cela dit, je considère toujours qu'il est légitime de vouloir savoir quelle heure il est dans un fuseau horaire quelconque, et cela pas seulement dans le but de vouloir afficher cette heure. Dans mon cas je veux conserver un timestamp dans le fuseau Europe/Paris. Je veux une valeur numérique et non une String.
    Ah bon. Et comment tu représenterais un timestamp sous forme numérique et pas String, toi ?

    Citation Envoyé par verbose Voir le message
    Le code que j'ai publié dans mon deuxième post marche très bien sur mon serveur hébergé aux US et donc ça me suffit. Mais du coup, je me demande si je ne détourne pas l'esprit dans lequel doit être utilisé Calendar compte tenu de ce que vous m'avez dit.
    Fondamentalement ça sert à rien d'utiliser un Calendar dans ton code. Tu ne fais qu'utiliser TimeZone.getOffset() et additionner des millisecondes. Le Calendar n'intervient pas là-dedans.

  11. #11
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    802
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 802
    Points : 653
    Points
    653
    Par défaut
    Mon timestamp est la valeur retournée par Calendar.getTimeInMillis(). C'est un choix discutable, mais c'est l'option que j'ai choisi et je ne souhaite pas le remettre en cause.

    D'une manière générale, puisqu'il est possible de définir la valeur du Calendar avec une valeur numérique pour un fuseau horaire quelconque, pourquoi ne serait-il pas possible de récupérer cette valeur numérique pour ce même fuseau ?

  12. #12
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 563
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 563
    Points : 21 627
    Points
    21 627
    Par défaut
    Et à ton avis, que représente exactement la valeur numérique donnée par Calendar.getTimeInMillis() ?

    Un nombre de millisecondes écoulées depuis le 1er Janvier 1970 à minuit pile, GMT.
    Autrement dit tu ne choisis pas à quelle time zone c'est associé, ce qui est la même chose que dire que c'est un nombre qui représente un instant dans le temps, indépendamment de la time zone.

    Citation Envoyé par verbose Voir le message
    D'une manière générale, puisqu'il est possible de définir la valeur du Calendar avec une valeur numérique pour un fuseau horaire quelconque
    Justement, ça ne l'est pas. Ou alors tu dois inventer ton propre, nouveau, mécanisme. La valeur numérique n'est pas associée à une time zone.

  13. #13
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    802
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 802
    Points : 653
    Points
    653
    Par défaut
    Ok merci thelvin

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [PHP 5.3] Gestion des fuseaux Horaires
    Par Anified dans le forum Langage
    Réponses: 3
    Dernier message: 23/06/2011, 14h57
  2. Gestion des decalages horaires en Java
    Par otam_otam dans le forum Langage
    Réponses: 1
    Dernier message: 09/11/2010, 19h22
  3. Gestion des fuseaux horaires(time.h et timezone)sous Linux
    Par adesport dans le forum Bibliothèque standard
    Réponses: 3
    Dernier message: 17/07/2008, 11h59
  4. [Timezone] Gestion des dates
    Par nezdeboeuf62 dans le forum GWT et Vaadin
    Réponses: 2
    Dernier message: 24/10/2007, 09h00
  5. Gestion des fuseaux horaires :-/
    Par kalash_jako dans le forum Général Conception Web
    Réponses: 9
    Dernier message: 23/04/2006, 23h02

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo