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

C Discussion :

Bogue dans mktime ?


Sujet :

C

  1. #1
    Membre actif
    Avatar de odsen.s
    Profil pro
    Étudiant
    Inscrit en
    Octobre 2006
    Messages
    269
    Détails du profil
    Informations personnelles :
    Âge : 34
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2006
    Messages : 269
    Points : 243
    Points
    243
    Par défaut Bogue dans mktime ?
    Bonjour à tous,

    Je suis en train de réaliser un petit projet d'agenda en C.
    Quelques tests sur certaines fonctions construites m'ammènent à constater un problème.

    Voici un premier exemple de code, qui fonctionne :
    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
    #include <stdio.h>
    #include <time.h>
     
    #define FMT_DATE "%d/%m/%Y"
     
    int main (void)
    {
       char s[100];
       struct tm *t_now = NULL;
     
       time_t tmt = time (NULL);
       t_now = localtime (&tmt);
     
       t_now->tm_mon -= 500;
       mktime(t_now);
     
       t_now->tm_mon -= 500;
       mktime(t_now);
     
       strftime (s, sizeof s, "Time = "FMT_DATE, t_now);
       puts(s);
     
       return 0;
    }
    Résultat:
    Nous avons retranché 500 mois, puis à nouveau 500 mois à la date actuelle, et le résultat est bon. Si on essaie de retrancher 1000 mois d'un seul coup (ce qui revient normalement au même) il y a un problème :
    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
    #include <stdio.h>
    #include <time.h>
     
    #define FMT_DATE "%d/%m/%Y"
     
    int main (void)
    {
       char s[100];
       struct tm *t_now = NULL;
     
       time_t tmt = time (NULL);
       t_now = localtime (&tmt);
     
       t_now->tm_mon -= 1000;
       mktime(t_now);
     
       strftime (s, sizeof s, "Time = "FMT_DATE, t_now);
       puts(s);
     
       return 0;
    }
    Résultat :
    Ici, on obtient un bogue.

    Quelqu'un saurait-il m'expliquer le problème ?
    Par avance, merci.

  2. #2
    Membre expérimenté
    Avatar de Gruik
    Profil pro
    Développeur Web
    Inscrit en
    Juillet 2003
    Messages
    1 566
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Juillet 2003
    Messages : 1 566
    Points : 1 727
    Points
    1 727
    Par défaut
    Salut,

    Citation Envoyé par man mktime
    Si la structure transmise ne peut pas être convertie, mktime() renvoie la valeur (time_t)(-1) et ne modifie pas les membres tm_wday et tm_yday.
    Je pense que dans les 2 cas, mktime echoue (et ne modifie donc pas la structure passée).
    Dans le premier cas, le premier mktime() reussit et positionne la date au 16/05/1924, le deuxieme echoue et laisse la date au 16/05/1924.
    Dans le deuxieme cas, mktime() echoue directement et ne met pas à jour les champs de la stcuture, ce qui signifie qu'on a un mois entre -1000 et -989 (0 à 11, moins 1000)

  3. #3
    Membre actif
    Avatar de odsen.s
    Profil pro
    Étudiant
    Inscrit en
    Octobre 2006
    Messages
    269
    Détails du profil
    Informations personnelles :
    Âge : 34
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2006
    Messages : 269
    Points : 243
    Points
    243
    Par défaut
    Dans le premier cas, le premier mktime() reussit et positionne la date au 16/05/1924, le deuxieme echoue et laisse la date au 16/05/1924.
    Je ne suis pas sûr, car 1000 mois correspondent à 83 ans, donc 1924 est bien la date attendue après les deux mktime.

  4. #4
    Membre expérimenté
    Avatar de Gruik
    Profil pro
    Développeur Web
    Inscrit en
    Juillet 2003
    Messages
    1 566
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Juillet 2003
    Messages : 1 566
    Points : 1 727
    Points
    1 727
    Par défaut
    Ok, dans ce cas, il ya peut etre une limite dans les valeurs "hors bornes" que peut prendre mktime

  5. #5
    Membre actif
    Avatar de odsen.s
    Profil pro
    Étudiant
    Inscrit en
    Octobre 2006
    Messages
    269
    Détails du profil
    Informations personnelles :
    Âge : 34
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2006
    Messages : 269
    Points : 243
    Points
    243
    Par défaut
    Citation Envoyé par Gruik Voir le message
    Ok, dans ce cas, il ya peut etre une limite dans les valeurs "hors bornes" que peut prendre mktime
    A priori, ça doit être ça.
    Dans la doc, je ne vois rien d'indiqué à ce sujet.
    Quoi qu'il en soit, mktime renvoit -1 (échoue) dans le second cas, il est alors possible d'agir en conséquence.
    Je trouvais simplement le comportement de la fonction curieux.

    Merci pour l'aide apportée

  6. #6
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par odsen.s Voir le message
    Je suis en train de réaliser un petit projet d'agenda en C.
    Quelques tests sur certaines fonctions construites m'ammènent à constater un problème.
    • Je conseille de travailler sur une copie et non sur la structure interne de localtime().
    • Il est impératif de s'assurer que mktime() a bien fait son travail en vérifiant la valeur retournée (-1 = Echec).
    • Apparamment, il y a une limite au nombre de mois que l'on peut retirer et cette limite semble dépendre de l'implémentation. Chez moi :
    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
    #include <stdio.h>
    #include <time.h>
     
    #define FMT_DATE "%d/%m/%Y"
     
    int main (void)
    {
       char s[100];
       struct tm tm_now = {0};
     
       time_t tmt = time (NULL);
       tm_now = *localtime (&tmt);
       strftime (s, sizeof s, "Time = "FMT_DATE, &tm_now);
       printf("%s (%16ld)\n",s, (long)tmt);
     
       tm_now.tm_mon -= 200;
       tmt = mktime(&tm_now);
       strftime (s, sizeof s, "Time = "FMT_DATE, &tm_now);
       printf("%s (%16ld)\n",s, (long)tmt);
     
       tm_now.tm_mon -= 500;
       tmt = mktime(&tm_now);
       strftime (s, sizeof s, "Time = "FMT_DATE, &tm_now);
       printf("%s (%16ld)\n",s, (long)tmt);
     
       return 0;
    }
    donne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    Time = 16/09/2007 (      1189976430)
    Time = 16/01/1991 (       664059630)
    Time = 16/05/1991 (              -1)
     
    Press ENTER to continue.
    Pas de Wi-Fi à la maison : CPL

  7. #7
    Membre actif
    Avatar de odsen.s
    Profil pro
    Étudiant
    Inscrit en
    Octobre 2006
    Messages
    269
    Détails du profil
    Informations personnelles :
    Âge : 34
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2006
    Messages : 269
    Points : 243
    Points
    243
    Par défaut
    Je conseille de travailler sur une copie et non sur la structure interne de localtime().
    Ok.

    # Il est impératif de s'assurer que mktime() a bien fait son travail en vérifiant la valeur retournée (-1 = Echec).
    # Apparamment, il y a une limite au nombre de mois que l'on peut retirer et cette limite semble dépendre de l'implémentation. Chez moi :
    <...>
    Merci pour ces infos Emmanuel

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

Discussions similaires

  1. Bogue dans la documentation de GTK_PRINT_SETTINGS_OUTPUT_FILE_FORMAT
    Par pvincent dans le forum GTK+ avec C & C++
    Réponses: 0
    Dernier message: 27/01/2015, 09h58
  2. Google accentue la chasse aux bogues dans ses produits
    Par Cedric Chevalier dans le forum Sécurité
    Réponses: 3
    Dernier message: 14/08/2013, 17h04
  3. [PDO] Bogue dans ma pagination
    Par dancom5 dans le forum PHP & Base de données
    Réponses: 2
    Dernier message: 13/06/2013, 10h41
  4. Bogue dans Qt Creator avec OSX ?
    Par mak972 dans le forum Qt Creator
    Réponses: 2
    Dernier message: 24/06/2010, 04h36

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