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

API standards et tierces Java Discussion :

DateValidator (1.3.1): Souci avec le cas :format "ww/y..y" et semaine 01/2013


Sujet :

API standards et tierces Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Homme Profil pro
    Développeur Java
    Inscrit en
    Octobre 2009
    Messages
    76
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Octobre 2009
    Messages : 76
    Par défaut DateValidator (1.3.1): Souci avec le cas :format "ww/y..y" et semaine 01/2013
    Bonjour à tous,

    Dans mon application, les saisies de dates via l'IHM se font suivant le format "semaine/année", "ww/yyyy"

    en utilisant la librairie [org.apache.commons.validator.DateValidator] version jar (commons-validator-1.3.1), la validation pour la semaine "01/2013" me retourne un false !?, pas de souci avec les semaines qui suivent...

    ci-dessous un bout de code permettant de tester ce cas particulier (01/2013)

    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
     
    import org.apache.commons.validator.DateValidator;
    public class DateValidationTest {
    	public static void main(String[] args) {
     
    		final DateValidator dateValidator = DateValidator.getInstance();
    		String weekStr = "01/2012";
    		boolean validBool = (dateValidator.isValid(weekStr, "ww/yyyy", false));
    		System.out.println("resultat validation semaine [" + weekStr +"] = " + validBool);
     
                    //Cas 01/2013
                    weekStr = "01/2013";
    		validBool = (dateValidator.isValid(weekStr, "ww/yyyy", false));
    		System.out.println("resultat validation semaine [" + weekStr +"] = " + validBool);
    	}
    }

    L'execution donne ce qui suit:

    resultat validation semaine [01/2012] = true
    resultat validation semaine [01/2013] = false
    La source du problème vient de la librairie DateValidator ?

    D'avance, Merci à tous pour vos réponses.

  2. #2
    Membre confirmé
    Homme Profil pro
    Développeur Java
    Inscrit en
    Octobre 2009
    Messages
    76
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Octobre 2009
    Messages : 76
    Par défaut
    Meme résultat avec une version plus récente : commons-validator-1.4.0

    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
     
    import java.util.Date;
    import org.apache.commons.validator.routines.DateValidator;
     
    public class DateValidationTest {
    	public static void main(String[] args) {
     
    		final DateValidator dateValidator = DateValidator.getInstance();
     
    		String weekStr = "01/2012";
    		Date date = dateValidator.validate(weekStr, "ww/yyyy");
    		System.out.println("resultat validation semaine [" + weekStr +"] = " + date);
     
    		weekStr = "52/2012";
    		date = dateValidator.validate(weekStr, "ww/yyyy");
    		System.out.println("resultat validation semaine [" + weekStr +"] = " + date);
     
    		weekStr = "53/2013";
    		date = dateValidator.validate(weekStr, "ww/yyyy");
    		System.out.println("resultat validation semaine [" + weekStr +"] = " + date);
     
    		weekStr = "01/2013";
    		date = dateValidator.validate(weekStr, "ww/yyyy");
    		System.out.println("resultat validation semaine [" + weekStr +"] = " + date);
     
     
    		weekStr = "02/2013";
    		date = dateValidator.validate(weekStr, "ww/yyyy");
    		System.out.println("resultat validation semaine [" + weekStr +"] = " + date);
    	}
    }


    resultat validation semaine [01/2012] = Mon Jan 02 00:00:00 CET 2012
    resultat validation semaine [52/2012] = Mon Dec 24 00:00:00 CET 2012
    resultat validation semaine [53/2013] = null
    resultat validation semaine [01/2013] = null
    resultat validation semaine [02/2013] = Mon Jan 07 00:00:00 CET 2013

  3. #3
    Modérateur

    Homme Profil pro
    Développeur java, access, sql server
    Inscrit en
    Octobre 2005
    Messages
    2 713
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur java, access, sql server
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 713
    Par défaut
    Qu'est-ce que ça donne avec
    Labor improbus omnia vincit un travail acharné vient à bout de tout - Ambroise Paré (1510-1590)

    Consulter sans modération la FAQ ainsi que les bons ouvrages : http://jmdoudoux.developpez.com/cours/developpons/java/

  4. #4
    Membre confirmé
    Homme Profil pro
    Développeur Java
    Inscrit en
    Octobre 2009
    Messages
    76
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Octobre 2009
    Messages : 76
    Par défaut
    Citation Envoyé par Népomucène Voir le message
    Qu'est-ce que ça donne avec
    Bonsoir,

    ça donne null

    resultat validation semaine [53/2012] = null

    Il y a certainement un problème coté DateFormat et les méthodes de parse en dessous

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    package org.apache.commons.validator.routines;
     
    public class DateValidator extends AbstractCalendarValidator {
       public Date validate(String value, String pattern) {
             return (Date)parse(value, pattern, (Locale)null, (TimeZone)null);
         }
    ...
     
    }

    la classe
    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
     
    package org.apache.commons.validator.routines;
     
    public abstract class AbstractCalendarValidator extends AbstractFormatValidator {
     
    /**
         * <p>Checks if the value is valid against a specified pattern.</p>
         *
         * @param value The value validation is being performed on.
         * @param pattern The pattern used to validate the value against, or the
         *        default for the <code>Locale</code> if <code>null</code>.
         * @param locale The locale to use for the date format, system default if null.
         * @param timeZone The Time Zone used to parse the date, system default if null.
         * @return The parsed value if valid or <code>null</code> if invalid.
         */
        protected Object parse(String value, String pattern, Locale locale, TimeZone timeZone) {
     
            value = (value == null ? null : value.trim());
            if (value == null || value.length() == 0) {
                return null;
            }
            DateFormat formatter = (DateFormat)getFormat(pattern, locale);
            if (timeZone != null) {
                formatter.setTimeZone(timeZone);
            }
            return parse(value, formatter);
     
        }
    }

    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
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
     
    /*
     * Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *      http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    package org.apache.commons.validator.routines;
     
    import java.text.Format;
    import java.text.ParsePosition;
    import java.util.Locale;
    import java.io.Serializable;
     
    /**
     * <p>Abstract class for <i>Format</i> based Validation.</p>
     *
     * <p>This is a <i>base</i> class for building Date and Number
     *    Validators using format parsing.</p>
     *
     * @version $Revision: 1227719 $ $Date: 2012-01-05 18:45:51 +0100 (Thu, 05 Jan 2012) $
     * @since Validator 1.3.0
     */
    public abstract class AbstractFormatValidator implements Serializable {
     
     /**
         * <p>Parse the value with the specified <code>Format</code>.</p>
         *
         * @param value The value to be parsed.
         * @param formatter The Format to parse the value with.
         * @return The parsed value if valid or <code>null</code> if invalid.
         */
        protected Object parse(String value, Format formatter) {
     
            ParsePosition pos = new ParsePosition(0);
            Object parsedValue = formatter.parseObject(value, pos);
            if (pos.getErrorIndex() > -1) {
                return null;
            }
     
            if (isStrict() && pos.getIndex() < value.length()) {
                return null;
            }
     
            if (parsedValue != null) {
                parsedValue = processParsedValue(parsedValue, formatter);
            }
     
            return parsedValue;
     
        }
     
    }

  5. #5
    Modérateur

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

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 582
    Par défaut
    Citation Envoyé par OrigineDeLaVie Voir le message
    Il y a certainement un problème coté DateFormat et les méthodes de parse en dessous
    Bien vu.

    Demonstration code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    public static void showSimpleDateFormatProblem() throws ParseException {
      DateFormat format = new SimpleDateFormat("ww/yyyy");
      format.setLenient(false);
     
      Object date = format.parse("01/2013");
      System.out.println(date);
    }
    Il y a bien une erreur remontée, mais elle n'est pas bien claire.
    Et on se demande bien pourquoi une erreur : on a juste demandé la première semaine de 2013.

    Notons au passage que sans la ligne format.setLenient(false) on a le résultat attendu. Bon, mais on ne devrait pas avoir besoin de leniency pour la date demandée.

    Voyons ce que dit la JavaDoc de DateFormat.setLenient() : en gros c'est juste un raccourci pour getCalendar().setLenient(false).

    Nouveau code de démonstration :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    public static void showSimpleDateFormatProblem2() throws ParseException {
      Calendar cal = Calendar.getInstance();
      cal.setLenient(false);
      cal.set(Calendar.WEEK_OF_YEAR, 1);
      cal.set(Calendar.YEAR, 2013);
      cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
     
      Date date = cal.getTime();
      System.out.println(date);
    }
    À nouveau une erreur, mais cette fois, le message est plus clair, et cette fois, on comprend pourquoi :
    nous avons demandé à la fois l'année 2013, la première semaine de l'année, et le lundi. Or, le lundi de la première semaine de 2013 n'est pas en 2013. Conflit. Si on veut faire des calculs de numéro de semaine avec un calendrier, il ne faut pas restreindre la leniency, puisque les semaines chevauchent les années et que leniency est contradictoire à cela.

    Si on ne demande pas de leniency, pas d'erreur, et on a le résultat voulu : le jour demandé étant l'année précédent l'année demandée, l'année est réajustée à 2012.
    Si on ne demande pas le lundi, ça dépend : le calendrier va garder le jour d'aujourd'hui, et on aura une erreur si on est lundi (dans la première semaine de 2013, seul lundi est en 2012,) et pas d'erreur un autre jour.
    SimpleDateFormat, bien sûr, renvoie toujours le premier jour concerné, ce qui signifie que derrière les rideaux il demande le lundi (pour nous autres français.)

    Mes conclusions :
    - Calendar n'a rien à se reprocher : les numéros de semaines sont ce qu'ils sont, setLenient() est ce qu'il est, les deux ne vont pas ensemble et ne doivent pas être mis ensemble.

    - SimpleDateFormat fait ce qu'il dit qu'il fait avec setLenient() : il le passe à Calendar sans se poser de question.
    Et du coup, on pourrait trouver que c'est pas le mieux : il devrait se poser des questions sur ce cas-là.
    Rappelons-nous quand même qu'un DateFormat produit des Dates, qui sont des instants dans le temps, et que le format demandé ici consiste à lire des semaines, qui ne sont pas des dates et se représentent mal comme des instants dans le temps. Les deux vont mal ensemble, et un SimpleDateFormat ne devrait sans doute pas intervenir sur cette question. Excuse qui ne va pas bien loin : parce qu'il ne marche pas mieux quand on lui indique à la fois le numéro de la semaine et un jour précis qui permet de résoudre l'ambiguïté Date <-> semaine.

    - DateValidator est essentiellement une surcouche de SimpleDateFormat. Même raisons mêmes conclusions : puisqu'il produit des Dates il est fatalement peu jouasse à gérer des semaines. En tout cas, puisque SimpleDateFormat le fait mal, il le fait mal aussi.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  6. #6
    Membre confirmé
    Homme Profil pro
    Développeur Java
    Inscrit en
    Octobre 2009
    Messages
    76
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Octobre 2009
    Messages : 76
    Par défaut
    Bonjour à tous et merci pour vos réponses,

    Donc, pour valider si la semaine (ww/yyyy) saisie, je devrais utiliser une autre solution qui ne s'appuie pas sur cette librairie qui est si on peut le dire boguée,

    Si c'est bien le cas (librairie boguée), comment remonter le bogue aux développeurs qui l'ont conçu ?

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

Discussions similaires

  1. [VBA] Soucis avec la Fonction Format
    Par kleenex dans le forum VBA Access
    Réponses: 4
    Dernier message: 11/06/2007, 11h17
  2. quelques soucis avec word 2000
    Par ramchou dans le forum Word
    Réponses: 3
    Dernier message: 06/09/2004, 18h13
  3. souci avec un algorithme
    Par slider16 dans le forum Algorithmes et structures de données
    Réponses: 4
    Dernier message: 22/03/2004, 17h17
  4. [DEBUTANT] petits soucis avec un prgm de chat
    Par LechucK dans le forum MFC
    Réponses: 8
    Dernier message: 19/01/2004, 16h52
  5. Réponses: 4
    Dernier message: 16/02/2003, 12h16

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