1. Bonjour tout le monde ! Veillez consulter la Politique de forum pour comprendre nos règles, Merci a vous !
    Rejeter la notice

WD Convertir une Date Heure au format ISO8601

Discussion dans 'Windev' créé par mma77, Mar 5, 2021.

  1. mma77

    mma77 New Member

    Inscrit:
    Mar 5, 2021
    Messages:
    10
    J'aime reçus:
    24
    Bonjour tout le monde,

    Pour ma première publication sur ce forum, je souhaiterais partager avec vous une fonction qui permet de convertir une chaine de caractères contenant une date et heure au format ISO8601 en une variable de type DateHeure exprimée en date et heure UTC (temps universel).

    Code (Text):
    PROCEDURE Iso8106ToDateTimeUTC(LOCAL sIsoDateTime est une chaîne ANSI)

    LOCAL
        dhMyDateTime est une DateHeure = Null
        sDate, sYear, sMonth, sDay, sWeek, sNbDays sont des chaînes ANSI = ""
        sTime, sHour, sMinute, sSecond, sDecimal sont des chaînes ANSI = ""
        sTimeZone, sHourZone, sMinuteZone, sOffsetZone sont des chaînes ANSI = ""
        dNewDate est un Date = Null

    SI (VérifieExpressionRégulière(sIsoDateTime,"([0-9]{4,4}[W0-9\-]*)[T]([0-9]{2,2}[0-9:.]*)([Z\+\-]{1,1}[0-9:]*)",sDate,sTime,sTimeZone) = Faux) ALORS RENVOYER(dhMyDateTime)

    VérifieExpressionRégulière(sDate,"([0-9]{4,4})[\-]{0,1}([0-9]{2,2})[\-]{0,1}([0-9]{2,2})",sYear,sMonth,sDay)
    SI (VérifieExpressionRégulière(sDate,"([0-9]{4,4})[\-]([0-9]{2,2})",sYear,sMonth) = Vrai) ALORS sDay = "01"
    VérifieExpressionRégulière(sDate,"([0-9]{4,4})[\-]{0,1}[W]([0-9]{2,2})[\-]{0,1}([1-7])",sYear,sWeek,sDay)
    SI (VérifieExpressionRégulière(sDate,"([0-9]{4,4})[\-]{0,1}[W]([0-9]{2,2})",sYear,sWeek) = Vrai) ALORS sDay = "1"
    SI (VérifieExpressionRégulière(sDate,"([0-9]{4,4})[\-]{0,1}([0-9]{3,3})",sYear,sNbDays) = Vrai) ALORS sMonth = "01";sDay = "01"

    SI (sYear = "") ALORS RENVOYER(dhMyDateTime)

    SI (sWeek <> "") ALORS
        SI (Val(sWeek) > 53) ALORS RENVOYER(dhMyDateTime)
        SI (Val(sWeek) = 0) ALORS RENVOYER(dhMyDateTime)
        dNewDate = SemaineVersDate(Val(sWeek), Val(sYear), iso8601)
        dNewDate..Jour += (Val(sDay) - 1)
        SI (DateValide(dNewDate) = Faux) ALORS RENVOYER(dhMyDateTime)
        sYear = NumériqueVersChaîne(dNewDate..Année,"04d")
        sMonth = NumériqueVersChaîne(dNewDate..Mois,"02d")
        sDay = NumériqueVersChaîne(dNewDate..Jour,"02d")
    FIN

    SI (sNbDays <> "") ALORS
        SI (Val(sNbDays) > 366) ALORS RENVOYER(dhMyDateTime)
        SI (Val(sNbDays) = 0) ALORS RENVOYER(dhMyDateTime)
        dNewDate = sYear+sMonth+sDay
        dNewDate..Jour += (Val(sNbDays) - 1)
        SI (DateValide(dNewDate) = Faux) ALORS RENVOYER(dhMyDateTime)
        sYear = NumériqueVersChaîne(dNewDate..Année,"04d")
        sMonth = NumériqueVersChaîne(dNewDate..Mois,"02d")
        sDay = NumériqueVersChaîne(dNewDate..Jour,"02d")
    FIN

    SI (DateValide(sYear+sMonth+sDay) = Faux) ALORS RENVOYER(dhMyDateTime)

    VérifieExpressionRégulière(sTime,"([0-9]{2,2})[:]{0,1}([0-9]{2,2})[:]{0,1}([0-9]{2,2})[.]([0-9]+)",sHour,sMinute,sSecond,sDecimal)
    SI (VérifieExpressionRégulière(sTime,"([0-9]{2,2})[:]{0,1}([0-9]{2,2})[:]{0,1}([0-9]{2,2})",sHour,sMinute,sSecond) = Vrai) ALORS sDecimal = "000"
    SI (VérifieExpressionRégulière(sTime,"([0-9]{2,2})[:]{0,1}([0-9]{2,2})",sHour,sMinute) = Vrai) ALORS sSecond = "00";sDecimal = "000"
    SI (VérifieExpressionRégulière(sTime,"([0-9]{2,2})",sHour) = Vrai) ALORS sMinute = "00";sSecond = "00";sDecimal = "000"

    SI (sHour = "") ALORS RENVOYER(dhMyDateTime)
    SI (HeureValide(sHour+sMinute+sSecond+sDecimal) = Faux) ALORS RENVOYER(dhMyDateTime)

    dhMyDateTime..PartieDate = sYear+sMonth+sDay
    dhMyDateTime..PartieHeure = sHour+sMinute+sSecond+sDecimal

    SI (VérifieExpressionRégulière(sTimeZone,"[Z]") = Faux) ALORS
        VérifieExpressionRégulière(sTimeZone,"([\+\-]{0,1})([0-9]{2,2})[:]{0,1}([0-9]{2,2})",sOffsetZone,sHourZone,sMinuteZone)
        SI (VérifieExpressionRégulière(sTimeZone,"([\+\-]{0,1})([0-9]{2,2})",sOffsetZone,sHourZone) = Vrai) ALORS sMinuteZone = "00"
        SI ((sOffsetZone = "") OU (sHourZone = "") OU (sMinuteZone = "")) ALORS dhMyDateTime = Null; RENVOYER(dhMyDateTime)
        SI ((sOffsetZone = "-") ET (sHourZone = "00") ET (sMinuteZone = "00")) ALORS dhMyDateTime = Null; RENVOYER(dhMyDateTime)
        SI ((sOffsetZone = "+") ET (sHourZone = "00") ET (sMinuteZone = "00")) ALORS RENVOYER(dhMyDateTime)
        SI (Val(sMinuteZone) > 59) ALORS dhMyDateTime = Null; RENVOYER(dhMyDateTime)
        SI ((Val(sMinuteZone) <> 0) ET (Val(sMinuteZone) <> 30) ET (Val(sMinuteZone) <> 45)) ALORS dhMyDateTime = Null; RENVOYER(dhMyDateTime)
        SI (sOffsetZone = "+") ALORS
            SI (Val(sHourZone) > 14) ALORS dhMyDateTime = Null; RENVOYER(dhMyDateTime)
            dhMyDateTime..Heure -= Val(sHourZone)
            dhMyDateTime..Minute -= Val(sMinuteZone)
        SINON
            SI (Val(sHourZone) > 12) ALORS dhMyDateTime = Null; RENVOYER(dhMyDateTime)
            dhMyDateTime..Heure += Val(sHourZone)
            dhMyDateTime..Minute += Val(sMinuteZone)
        FIN
    FIN

    RENVOYER(dhMyDateTime)
    Wiki ISO8106 :

    Bonjour visiteur, Merci de vous Inscrire ou de vous connectez pour voir les liens!



    Si vous avez des commentaires, je suis preneur.

    Cordialement,
    mma77
     
    Pascal, cyberripper et netrad aiment ça.
  2. popoy

    popoy Well-Known Member
    MEMBRE WX

    Inscrit:
    Fev 23, 2018
    Messages:
    2,934
    J'aime reçus:
    1,563
    Salut

    Bonjour visiteur, Merci de vous Inscrire ou de vous connectez pour voir les liens!

    , et bienvenue sur le forum.

    Il serait intéressant d'avoir aussi la fonction inverse
    C'est-à-dire de dateheure UTC en wlangage vers ISO 8601
     
  3. JeAn-PhI

    JeAn-PhI New Member

    Inscrit:
    Juin 17, 2020
    Messages:
    17
    J'aime reçus:
    6
    bonjour,

    à partir de la version 25 :

    Code (Text):
    Res = ChaîneVersDate("2019-08-25T00:00:00.000+02:00", maskDateInternet) // Res = "20190825000000000"
    Res = ChaîneVersDate("2019-08-24T22:00:00.000Z", maskDateInternetUTC) // Res = "20190824220000000"
     
    Pascal apprécie ceci.
  4. popoy

    popoy Well-Known Member
    MEMBRE WX

    Inscrit:
    Fev 23, 2018
    Messages:
    2,934
    J'aime reçus:
    1,563

    Bonjour visiteur, Merci de vous Inscrire ou de vous connectez pour voir les liens!

    ça c'est la RFC-3339
    C'est assez proche de l'ISO 8601
    En plus

    Bonjour visiteur, Merci de vous Inscrire ou de vous connectez pour voir les liens!

    fait une vérification du Format ISO 8601
     
  5. mma77

    mma77 New Member

    Inscrit:
    Mar 5, 2021
    Messages:
    10
    J'aime reçus:
    24
    Bonjour,
    Merci pour vos retours et votre accueil.

    Pour la fonction inverse dateheure UTC en wlangage vers ISO 8601 c'est assez simple :
    Code (Text):
    LOCAL
        dhDateHeure est un DateHeure = DateHeureLocaleVersUTC(DateHeureSys())
        sDateHeureISO8106 est une chaîne = ChaîneConstruit("%1T%2Z",DateVersChaîne(dhDateHeure..PartieDate,"AAAA-MM-JJ"),HeureVersChaîne(dhDateHeure..PartieHeure,"HH:MM:SS"))
    Par contre ce qui pourrait être bien c'est la fonction inverse en fonction de la timezone passée en paramètre voir même en fonction du format de l'ISO8106 voulu.

    Je n'ai pas la version 25 donc je ne connaissais pas les constantes maskDateInternet et maskDateInternetUTC pour convertir une date au format de la norme RFC-3339. Merci pour l'info JeAn-PhI

    Cordialement
    mma77

    PS : C'est dommage que sur ce forum, il n'y a pas une section dédiée pour partager du code et des exemples et une autre section dédiée au questions et problèmes rencontrés.
     
    Pascal, cyberripper et Gemini1961 aiment ça.
  6. popoy

    popoy Well-Known Member
    MEMBRE WX

    Inscrit:
    Fev 23, 2018
    Messages:
    2,934
    J'aime reçus:
    1,563
    Si ça existe c'est la partie ressources
    Mais je ne sais si tu y a accès
    Mais tu peux mettre un lien méga ou d'un autre cloud si tu veux.
     
  7. cyberripper

    cyberripper Active Member
    MEMBRE WX DUMP TEAM

    Inscrit:
    Jan 26, 2018
    Messages:
    76
    J'aime reçus:
    176
    Bonjour et bienvenue parmis nous

    Bonjour visiteur, Merci de vous Inscrire ou de vous connectez pour voir les liens!


    Merci de partager ton experience avec nous sur ce forum.

    @+ Cyber
     
    mma77 apprécie ceci.
  8. Pascal

    Pascal Active Member
    MEMBRE WX

    Inscrit:
    Fev 11, 2018
    Messages:
    82
    J'aime reçus:
    126
    Bonjour

    Bonjour visiteur, Merci de vous Inscrire ou de vous connectez pour voir les liens!



    Si cela t'intéresse et si tu souhaites écrire la fonction inverse voici un bout de code pour récupérer la timezone du poste :

    Code (Text):
    _SYSTEMTIME est une Structure
        nYear est un entier sans signe sur 2 octets // WORD wYear;
        nMonth est un entier sans signe sur 2 octets //    WORD wMonth;
        nDayOfWeek est un entier sans signe sur 2 octets //    WORD wDayOfWeek;
        nDay est un entier sans signe sur 2 octets // WORD wDay;
        nHour est un entier sans signe sur 2 octets // WORD wHour;
        nMinute est un entier sans signe sur 2 octets // WORD wMinute;
        nSecond est un entier sans signe sur 2 octets // WORD wSecond;
        nMilliseconds est un entier sans signe sur 2 octets // WORD wMilliseconds;
    FIN

    _TIME_DYNAMIC_ZONE_INFORMATION est une Structure
        nBias est un entier sur 4 octets // LONG Bias;
        sStandardName est une chaîne UNICODE sur 31 // WCHAR StandardName[32];
        stStandardDate est un _SYSTEMTIME // SYSTEMTIME StandardDate;
        nStandardBias est un entier sur 4 octets //    LONG StandardBias;
        sDaylightName est une chaîne UNICODE sur 31 // WCHAR DaylightName[32];
        stDaylightDate est un _SYSTEMTIME // SYSTEMTIME DaylightDate;
        nDaylightBias est un entier sur 4 octets //    LONG DaylightBias;
        sTimeZoneKeyName est une chaîne UNICODE sur 127 // WCHAR TimeZoneKeyName[128];
        nDynamicDaylightTimeDisabled est un entier sans signe sur 1 octet // BOOLEAN DynamicDaylightTimeDisabled;
    FIN

    stTIME_DYNAMIC_ZONE_INFORMATION est un _TIME_DYNAMIC_ZONE_INFORMATION
    nResult est un entier sans signe sur 4 octets
    nResult = API("Kernel32.dll","GetDynamicTimeZoneInformation",&stTIME_DYNAMIC_ZONE_INFORMATION)
    SELON nResult
        CAS 0 OU 1 :
            Trace("Nom du fuseau horaire : " + UnicodeVersAnsi(stTIME_DYNAMIC_ZONE_INFORMATION:sStandardName))
            Trace("Différence entre le temps universel (UTC) et l'heure locale (en minutes) : " + NumériqueVersChaîne(stTIME_DYNAMIC_ZONE_INFORMATION:nBias))
        CAS 2 :
            Trace("Nom du fuseau horaire : " + UnicodeVersAnsi(stTIME_DYNAMIC_ZONE_INFORMATION:sDaylightName))
            Trace("Différence entre le temps universel (UTC) et l'heure locale (en minutes) : " + NumériqueVersChaîne(stTIME_DYNAMIC_ZONE_INFORMATION:nBias + stTIME_DYNAMIC_ZONE_INFORMATION:nDaylightBias))
        AUTRE CAS
            Trace(ErreurInfo())
    FIN
    Cordialement,
    Pascal
     
  9. mma77

    mma77 New Member

    Inscrit:
    Mar 5, 2021
    Messages:
    10
    J'aime reçus:
    24
    Bonjour et merci Pascal pour ton code.

    C'est exactement pour cela que je me suis inscrit sur ce forum pour pouvoir échanger sur des sujets et partager du code entre membres.
    Bon c'est un peu dommage qu'il n'y a pas plus de partage de code à par dans les anciennes publications et surtout une section réservé à cet effet.

    Si je peux me permettre et si tu es intéressé, tu devrais peut-être faire une publication sur ce sujet de timezone et l'approfondir un peu avec :
    - La récupération de la date de passage en heure d'été et d'hiver.
    - La modification de la timezone du poste avec la fonction "SetDynamicTimeZoneInformation".
    - L'activation et la désactivation du passage en heure d'été et d'hiver.
    etc..

    Merci encore Pascal pour ton partage de code.
    Au plaisir.
    mma77
     
    Pascal, WX1331 et cyberripper aiment ça.

Partager cette page

Chargement...