PC SOFT

PROFESSIONAL NEWSGROUPS
WINDEVWEBDEV and WINDEV Mobile

Home → WINDEV 26 → [WD16] DateValide
[WD16] DateValide
Started by GUERVILLE, Jun., 17 2011 4:09 PM - 8 replies
Posted on June, 17 2011 - 4:09 PM
Bonjour,

Je dois analyser une date dans un fichier texte
MAis je ne connais pas son format, ni même si elle sera valide
Je peux donc recevoir le date comme ceci
16/05/2011
16/05/11
20111605
16-05-2011
16-05-11
J'ai constaté que la fonction date valide ne marche pas par exemple avec 16/05/11

Ma question. Comment tester si la date est valide et comment la convertir systematiquement en date AAAAMMJJte
Registered member
67 messages
Posted on June, 17 2011 - 6:35 PM
Bonjour,

effectivement, il y a quelque soucis avec DateValide()
Voici ce code qui "fonctionne" (voir remarque plus loin)
DateàTester est une chaîne = "20110516" //"20x10x16"
dResdate est une Date
tabFormatDate est un tableau de 5 chaînes
i est un entier
Num est un entier
tabFormatDate[1] = "AAAAMMJJ"
tabFormatDate[2] = "JJ/MM/AA"
tabFormatDate[3] = "JJ/MM/AAAA"
tabFormatDate[4] = "JJ_MM_AAAA"
tabFormatDate[5] = "JJ-MM-AA"
POUR i = 1 A 5
dResdate = ChaîneVersDate(DateàTester,tabFormatDate[i])
SI DateValide(dResdate) = Vrai ALORS
Num = i
SORTIR
FIN
dResdate = ""
FIN
SI Num = 0 ALORS
Trace("Format inconnu")
SINON
Trace(dResdate, tabFormatDate[Num], Num)
FIN

Remarques:
1/ il est nécessaire de tester en premier le format "AAAAMMJJ", sinon avec la date testée dans le programme, ça renvoie 20161020 (selon le format "JJ/MM/AA"), car l'instruction DateValide ne teste apparemment pas la nature des séparateurs
2/ 20/10/16 ou 20 10*16 etc... vont renvoyer la date correcte 20161020
3/ en fait, il faudrait tester avant tout si tout les caractères de la date à tester sont des entiers car avec "20110516" à tester, ça donne "20110516" avec le format 1 et "20161020" avec le format 2 alors danger.

Ce n'est certainement pas tout...

Une requête au ST serait souhaitable!

Bondev,
Eric
Registered member
67 messages
Posted on June, 17 2011 - 6:41 PM
en complement à ma réponse précédente:
- les formats 4 et 5 sont inutiles car 20/11/2011 comme 20-11*2016 vont renvoyer le même bon résultat.
- "20111516" n'est pas valide selon le format 1 mais renvoie "20161120" en otant le 3eme et 6eme caractères selon le format 2. Dangereux.

voila
Posted on June, 17 2011 - 11:44 PM
Merci :)
Posted on June, 23 2011 - 2:59 PM
Bonjour,

Je crois que vous feriez bien d'aller consulter l'aide sur DateValide :
Cette fonction n'accepte que des variables Date ou une chaîne formatée en AAAAMMJJ.

Cette fonction n'a donc pas vocation à tester des dates avec tout type de séparateur.

Bon dev
Registered member
67 messages
Posted on June, 23 2011 - 4:03 PM
Bonjour Olivier,

c'est tout à fait exact, c'est pourquoi il est nécessaire d'utiliser
ChaîneVersDate() avec différents formats. Mais ça n'est pas si simple que cela.
Le DateValide() fonctionne bien, mais il faut faire très attention à l'utilisation de ChaîneVersDate() !

Eric
Posted on August, 03 2021 - 5:43 PM
Je déterre ce sujet car j’ai également un problème avec ChaîneVersDate quand je ne connais pas le format à l'avance.
Le code suivant a été testé en 24, 25 et 26 et donne le même résultat.

w_format_date_tolere est un tableau de 25 chaînes
w_format_date_nb est un entier
wch1 est une Date
wi est un entier=0
MaChaineDate est une chaîne="04/06/2021"

wi++
w_format_date_tolere[wi]="AAAAMMJJ"
wi++
w_format_date_tolere[wi]="AAMMJJ"
wi++
w_format_date_tolere[wi]="JJMMAAAA"
wi++
w_format_date_tolere[wi]="JJMMAA"
wi++
w_format_date_tolere[wi]="JJ/MM/AAAA"
wi++
w_format_date_tolere[wi]="J/M/AAAA"
wi++
w_format_date_tolere[wi]="JJ/MM/AA"
wi++
w_format_date_tolere[wi]="J/M/AA"
wi++
w_format_date_tolere[wi]="AAAA/MM/JJ"
wi++
w_format_date_tolere[wi]="AAAA/M/J"
wi++
w_format_date_tolere[wi]="AA/MM/JJ"
wi++
w_format_date_tolere[wi]="AA/M/J"
w_format_date_nb=wi
POUR wj=1 À w_format_date_nb
wch1=ChaîneVersDate(MaChaineDate,w_format_date_tolere[wj])
Trace(w_format_date_tolere[wj] + " " + MaChaineDate + "=> " + wch1)
FIN


Le résultat est

AAAAMMJJ 04/06/2021=> 00040620
AAMMJJ 04/06/2021=>
JJMMAAAA 04/06/2021=>
JJMMAA 04/06/2021=>
JJ/MM/AAAA 04/06/2021=> 20210604
J/M/AAAA 04/06/2021=> 20210604
JJ/MM/AA 04/06/2021=>
J/M/AA 04/06/2021=>
AAAA/MM/JJ 04/06/2021=>
AAAA/M/J 04/06/2021=>
AA/MM/JJ 04/06/2021=> 20040620
AA/M/J 04/06/2021=> 20040620

Si il faut tester AAAAMMJJ en premier, il serait bon qu'il ne renvoi pas de résultat incohérent.
D'ailleur, pourquoi AAAAMMJJ renvoi un résultat alors que JJMMAAAA non ?
Avec la date que j'ai attribué, seul JJ/MM/AAAA devrait renvoyer un résultat, ou au pire J/M/AAAA
Registered member
350 messages
Posted on August, 04 2021 - 10:21 AM
Déterrer un sujet vieux de 10 ans n'apportera rien d'utile ...
Il faudrait créer un nouveau sujet...
Posted on August, 04 2021 - 10:47 AM
De plus, dans l'exemple précédent, "AMMJJ" peut être confondu avec "JJMMA" de la même manière que "AA/MM/JJ" et "JJ/MM/AA"
Enfin "AA/MM/JJ" trouvait le résultat "20040620" qui se trouve être une date valide mais qui est totalement fausse au regard de la date initiale "04/06/2021"

Afin de réduire les erreurs j'ai mis en place la solution suivante. Elle n'est pas parfaite certes, mais elle solutionne la majorité des cas que je rencontre.

w_format_date est un tableau associatif de chaînes
W_patern est un tableau associatif de chaînes

w_format_date_nb est un entier
wch1 est une Date
wi est un entier= 0
MaChaineDate est une chaîne = "04/06/2021"

wi=0
wi++
W_patern[wi]="[1-9]{1}[0-9]{3}[0-1]{1}[0-9]{1}[0-3]{1}[0-9]{1}"
w_format_date[wi]="AAAAMMJJ"
wi++
W_patern[wi]="[0-9]{2}[0-1]{1}[0-9]{1}[0-3]{1}[0-9]{1}"
w_format_date[wi]="AAMMJJ"
wi++
W_patern[wi]="[0-3]{1}[0-9]{1}[0-1]{1}[0-9]{1}[1-9]{1}[0-9]{3}"
w_format_date[wi]="JJMMAAAA"
wi++
W_patern[wi]="[0-3]{1}[0-9]{1}[0-1]{1}[0-9]{1}[0-9]{2}"
w_format_date[wi]="JJMMAA"
wi++
W_patern[wi]="[0-3]{1}[0-9]{1}[\/]{1}[0-1]{1}[0-9]{1}[\/]{1}[1-9]{1}[0-9]{3}"
w_format_date[wi]="JJ/MM/AAAA"
wi++
W_patern[wi]="[1-3]?[0-9]{1}[\/]{1}[1]?[0-9]{1}[\/]{1}[1-9]{1}[0-9]{3}"
w_format_date[wi]="J/M/AAAA"
wi++
W_patern[wi]="[1-3]{1}[0-9]{1}[\/]{1}[0-1]{1}[0-9]{1}[\/]{1}[0-9]{2}"
w_format_date[wi]="JJ/MM/AA"
wi++
W_patern[wi]="[1-3]?[0-9]{1}[\/]{1}[1]?[0-9]{1}[\/]{1}[0-9]{2}"
w_format_date[wi]="J/M/AA"
wi++
W_patern[wi]="[1-9]{1}[0-9]{3}[\/]{1}[0-1]{1}[0-9]{1}[\/]{1}[0-3]{1}[0-9]{1}"
w_format_date[wi]="AAAA/MM/JJ"
wi++
W_patern[wi]="[1-9]{1}[0-9]{3}[\/]{1}[1]?[0-9]{1}[\/]{1}[1-3]?[0-9]{1}"
w_format_date[wi]="AAAA/M/J"
wi++
W_patern[wi]="[0-9]{2}[\/]{1}[0-1]{1}[0-9]{1}[\/]{1}[0-3]{1}[0-9]{1}"
w_format_date[wi]="AA/MM/JJ"
wi++
W_patern[wi]= "[0-9]{2}[\/]{1}[1]?[0-9]{1}[\/]{1}[1-3]?[0-9]{1}"
w_format_date[wi] = "AA/M/J"

w_format_date_nb= wi

POUR wj=1 À w_format_date_nb
SI VérifieExpressionRégulière(MaChaineDate, W_patern[wj])=Vrai ALORS
wch1=ChaîneVersDate(MaChaineDate,w_format_date[wj])
SI DateValide(wch1) ALORS
//traitements
Trace(Complète(w_format_date[wj],12," ") + MaChaineDate + "=> " + wch1)
FIN
FIN
FIN


Si quelqu'un a une solution plus précise, qu'il n'hésite pas.