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

Collection et Stream Java Discussion :

Changement du jour de la semaine avec java.util.GregorianCalendar


Sujet :

Collection et Stream Java

  1. #1
    Membre expert
    Avatar de Alexandre T
    Homme Profil pro
    Chef de projets AMO
    Inscrit en
    Mai 2002
    Messages
    1 213
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Chef de projets AMO
    Secteur : Transports

    Informations forums :
    Inscription : Mai 2002
    Messages : 1 213
    Points : 3 001
    Points
    3 001
    Par défaut Changement du jour de la semaine avec java.util.GregorianCalendar
    Bonjour,

    Je rencontre de grandes difficultés avec la fonction set de GregorianCalendar quand il s'agit de changer le jour de la semaine. Je n'arrive pas toujours à reproduire le comportement qui me paraît suspect.

    Après trois bonnes heures de tatonnement pour le reproduire , j'en arrive à cela :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");       
    GregorianCalendar ld_date = (GregorianCalendar)date.clone();
    String ls_date = simpleDateFormat.format(ld_date.getTime());
           ld_date.set(GregorianCalendar.DAY_OF_WEEK,GregorianCalendar.TUESDAY);
    ls_date = simpleDateFormat.format(ld_date.getTime());
    En paramètre au code de la fonction ci-dessus je transmet date une instance de GregorianCalendar, dont la valeur est le 11 février 2007 00:00:00

    La variable ls_date contient la chaîne de caractère 2007-02-06. C'est juste, n'est-ce-pas ?

    Je modifie mon code pour obtenir :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");       
    GregorianCalendar ld_date = (GregorianCalendar)date.clone();
    //String ls_date = simpleDateFormat.format(ld_date.getTime());
           ld_date.set(GregorianCalendar.DAY_OF_WEEK,GregorianCalendar.TUESDAY);
    String ls_date = simpleDateFormat.format(ld_date.getTime());
    La variable ls_date contient la chaîne de caractère 2007-02-11. C'est étonnant, non ?

    Voyez-vous une explication à cela ?
    Parvenez-vous à reproduire ce constat ?

  2. #2
    Membre expert
    Avatar de Alexandre T
    Homme Profil pro
    Chef de projets AMO
    Inscrit en
    Mai 2002
    Messages
    1 213
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Chef de projets AMO
    Secteur : Transports

    Informations forums :
    Inscription : Mai 2002
    Messages : 1 213
    Points : 3 001
    Points
    3 001
    Par défaut
    Je précise que je ne rencontre AUCUNE difficulté si je m'amuse à modifier le jour du mois et non celui de la semaine en utilisant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ld_date.set(GregorianCalendar.DAY_OF_MONTH,2);
    La variable ls_date vaudra dans un cas comme dans l'autre 2007-02-02.

  3. #3
    Membre chevronné
    Avatar de Deadpool
    Homme Profil pro
    Inscrit en
    Novembre 2005
    Messages
    1 312
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Novembre 2005
    Messages : 1 312
    Points : 2 011
    Points
    2 011
    Par défaut
    Salut.

    J'ai testé ton bout de code sous linux avec une jvm 1.6 et j'ai constaté la même chose.

    Mais là, je t'avoue que je ne comprend pas non plus.

    Je cherche, je cherche...

  4. #4
    Membre actif
    Homme Profil pro
    Architecte de système d'information
    Inscrit en
    Mars 2002
    Messages
    192
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Architecte de système d'information

    Informations forums :
    Inscription : Mars 2002
    Messages : 192
    Points : 252
    Points
    252
    Par défaut
    Salut,

    j'ai rencontré le même type de problème que toi.
    Mon contournement a été d'utiliser JodaTime...

    Maintenant j'ai quand même la solution à ton problème, en cherchant dans le bug tracker de sun, on tombe là dessus : bug 4655637.

    La solution est donc de repositionner correctement la semaine comme ci-après:
    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
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    public class TestDate {
    	private static SimpleDateFormat SDF = new SimpleDateFormat("dd/MM/yyyy");
     
    	/**
             * @param args
             */
    	public static void main(String[] args) {
    		GregorianCalendar gc = new GregorianCalendar(2007,1,11);
     
    		changeDay1((GregorianCalendar)gc.clone());
    		changeDay2((GregorianCalendar)gc.clone());
    	}
     
    	private static void changeDay1(GregorianCalendar gc) {
    		System.out.println("Methode 1");
    //		System.out.println(SDF.format(gc.getTime()));
    		gc.set(GregorianCalendar.DAY_OF_WEEK,GregorianCalendar.TUESDAY);
    		System.out.println(SDF.format(gc.getTime()));
    		System.out.println("");
    	}
     
    	private static void changeDay2(GregorianCalendar gc) {
    		System.out.println("Methode 2");
    //		System.out.println(SDF.format(gc.getTime()));
    		int weekOfYear = gc.get(GregorianCalendar.WEEK_OF_YEAR);
    		gc.set(GregorianCalendar.DAY_OF_WEEK,GregorianCalendar.TUESDAY);
    		gc.set(GregorianCalendar.WEEK_OF_YEAR,weekOfYear);
    		System.out.println(SDF.format(gc.getTime()));
    		System.out.println("");
    	}
    }
    Il est clair que quand on rencontre des problèmes comme ceux là, on se dit que vivement que l'API Date change dans le jdk.

    Pour ma part si tu as la possibilité de rajouter une dépendance sur ton projet, utilise JodaTime. Les APIs sont propres, claires et faciles à utiliser.
    Au pire, tu peux même utiliser JodaTime en interne et sur tes interfaces publiques utiliser les classes du JDK. JodaTime propose des classes de conversion entre classes du JDK et leurs propores implémentations.

    Bon courage !

  5. #5
    Membre expert
    Avatar de Alexandre T
    Homme Profil pro
    Chef de projets AMO
    Inscrit en
    Mai 2002
    Messages
    1 213
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Chef de projets AMO
    Secteur : Transports

    Informations forums :
    Inscription : Mai 2002
    Messages : 1 213
    Points : 3 001
    Points
    3 001
    Par défaut
    Je vous remercie tous les deux. En somme, j'ai gardé ma solution : Appeler la méthode getTime une fois supplémentaire. Il est clair que ce bug est important.

    J'avais fait une recherche sur le bug tracker de Sun, mais je n'avais pas vu cela.

    Ce qui est important à mon sens est leur réponse :
    When computing time (milliseconds), GregorianCalendar leaves some fields inconsistent. Then, after the last set(DAY_OF_WEEK), an invalid (older) WEEK_OF_MONTH value is used in the last getTime() call.
    xxxxx@xxxxx 2002-03-22
    Citation Envoyé par Alexandre T. (dans une tentative de traduction)
    En calculant une date, [La classe] GregorianCalendar laisse quelques champs "non initialisés".
    En clair, il faut forcer l'initialisation de tous les champs, ce qui se produit avec getTime().

    Je trouve en tout cas cette optimisation particulièrement dangereuse. Je pensais que le problème venait de l'utilisation de la méthode clone.

    Merci à tous.

    Je note cela comme corrigé. Je vais me renseigner sur JodaTime, mais pour l'instant ce développement-ci restera tel quel faute de temps.

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

Discussions similaires

  1. Jour de la semaine avec GregorianCalendar
    Par xav3601 dans le forum Langage
    Réponses: 3
    Dernier message: 12/03/2010, 10h27
  2. Réponses: 6
    Dernier message: 18/09/2009, 14h30
  3. Comment calculer un jour de la semaine avec Joda
    Par ttttnht dans le forum API standards et tierces
    Réponses: 6
    Dernier message: 08/09/2008, 17h54
  4. Changement de la base de données avec java
    Par ruby_robber dans le forum BIRT
    Réponses: 3
    Dernier message: 24/10/2007, 13h08
  5. probleme avec java.util.Scanner
    Par d-a-v-e dans le forum Eclipse Java
    Réponses: 4
    Dernier message: 04/05/2006, 22h08

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