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 :

opération sur les dates et les heures


Sujet :

C

  1. #1
    Membre du Club
    Profil pro
    Consultant
    Inscrit en
    Mars 2007
    Messages
    59
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations professionnelles :
    Activité : Consultant

    Informations forums :
    Inscription : Mars 2007
    Messages : 59
    Points : 63
    Points
    63
    Par défaut opération sur les dates et les heures
    Bonjour,

    J'ai une fonction qui me retourne l'heure et la date sous le format d'une chaine de caractère.

    Je souhaiterai faire des opérations sur la date et l'heure.
    Par exemple:
    - la date est le 31.12.07. Je voudrais rajouter un jour à la date.
    La valeur de la date deviendra 01.01.08.

    - Un autre cas, la date est le 01.01.08 et l'heure est 00:05. Je voudrais retrancher une heure.
    La valeur de la date sera 31.12.07 et l'heure sera 23:05.

    Exist-il une bibliothèque en c pour faire cela?


    Merci

    Bertrand

  2. #2
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Il faut transformer la date en un type numérique (comme le type standard time_t qui représente un nombre de secondes depuis je-ne-sais-plus-quelle-date) et faire une simple addition ou soustraction sur ce nombre (dans le cas de secondes, tu ajoutes un jour en ajoutant 86400 secondes et tu retranches une heure en soustrayant 3600 secondes...)
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  3. #3
    Rédacteur
    Avatar de Vincent Rogier
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    2 373
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 2 373
    Points : 5 307
    Points
    5 307
    Par défaut
    Faut faire 3 steps :
    • construire un time_t à partir de ta chaine de charactères (par sscanf() par exemple)
    • faire tes opérations sur ton time_t
    • reconvertir le time_t en chaine par un printf ou un asctime ou strftime
    Vincent Rogier.

    Rubrique ORACLE : Accueil - Forum - Tutoriels - FAQ - Livres - Blog

    Vous voulez contribuer à la rubrique Oracle ? Contactez la rubrique !

    OCILIB (C Driver for Oracle)

    Librairie C Open Source multi-plateformes pour accéder et manipuler des bases de données Oracle

  4. #4
    Membre du Club
    Profil pro
    Consultant
    Inscrit en
    Mars 2007
    Messages
    59
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations professionnelles :
    Activité : Consultant

    Informations forums :
    Inscription : Mars 2007
    Messages : 59
    Points : 63
    Points
    63
    Par défaut
    Je n'ai pas vu dans <time.h> des opérations de calcule des dates et heures sur une structure "struct tm".

    Quels sont les noms de ces fonctions?

  5. #5
    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 beb1982 Voir le message
    J'ai une fonction qui me retourne l'heure et la date sous le format d'une chaine de caractère.

    Je souhaiterai faire des opérations sur la date et l'heure.
    Par exemple:
    - la date est le 31.12.07. Je voudrais rajouter un jour à la date.
    La valeur de la date deviendra 01.01.08.

    - Un autre cas, la date est le 01.01.08 et l'heure est 00:05. Je voudrais retrancher une heure.
    La valeur de la date sera 31.12.07 et l'heure sera 23:05.

    Exist-il une bibliothèque en c pour faire cela?
    C'est plus compliqué qu'il n'y parait. Je conseille de commencer par apprendre à manipuler struct tm et mktime(). Pour ce que tu veux faire, il suffit d'ajouter la valeur en jour, heure etc. au champ correspondant et de rappeler mktime() qui va faire l'ajustement automatiquement. La structure doit avoir été initialisée à 0 avant toute appel de mktime().

    Ensuite, il faut convertir les chaines en nombres pour en faire un struct tm. Il y a pas mal de pièges, bien lire la doc des fonctions de <time.h>.

    Pour un affichage rapide, ctime() peut aider. Pour un affichage contrôlé, strftime() est très puissante.
    Pas de Wi-Fi à la maison : CPL

  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 vicenzo Voir le message
    • construire un time_t à partir de ta chaine de charactères (par sscanf() par exemple)
    Non.
    Pas de Wi-Fi à la maison : CPL

  7. #7
    Rédacteur
    Avatar de Vincent Rogier
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    2 373
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 2 373
    Points : 5 307
    Points
    5 307
    Par défaut
    Citation Envoyé par Emmanuel Delahaye Voir le message
    Non.
    Ma réponse était évidemment un raccourci ...

    Voici un exemple (sans gestion de contrôle de validation de date... mais bon !)

    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
     
     #define NB_TIME_ARGS 6
     
    int main (int argc, char** argv)
    {
        time_t tmt = 0;
        struct tm t = {0};
     
        char str[100];
     
        /* date - heure courante */
     
        time (&tmt);
        strftime(str, sizeof(str)-1, "%d/%m/%Y %H:%M:%S", localtime (&tmt));
     
        /* récupération des valeurs */
     
        if (NB_TIME_ARGS == sscanf(str, "%02d/%02d/%04d %02d:%02d:%02d",
                                    &t.tm_mday, &t.tm_mon, &t.tm_year,
                                    &t.tm_hour, &t.tm_min, &t.tm_sec))
     
        {
             /* correction des valeurs */
            t.tm_year -= 1900;
            t.tm_mon--;
            t.tm_isdst = 1; /* gestion heure été / hivers */
     
            tmt=mktime(&t);
     
             /* on ajoute 1 heure  pour le test */
     
            tmt+=3600;
     
             /* reconversion en chaine de charactères */
            strftime(str, sizeof(str)-1, "%d/%m/%Y %H:%M:%S", localtime(&tmt));
     
            printf(str);
        }
     
        return 1
    }
    Vincent Rogier.

    Rubrique ORACLE : Accueil - Forum - Tutoriels - FAQ - Livres - Blog

    Vous voulez contribuer à la rubrique Oracle ? Contactez la rubrique !

    OCILIB (C Driver for Oracle)

    Librairie C Open Source multi-plateformes pour accéder et manipuler des bases de données Oracle

  8. #8
    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 vicenzo Voir le message
    Ma réponse était évidemment un raccourci ...

    Voici un exemple (sans gestion de contrôle de validation de date... mais bon !)
    Que c'est compliqué...
    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
     
    #include <time.h>
    #include <stdio.h>
     
    int main (void)
    {
       #define FMT_DATE "%d/%m/%Y %H:%M:%S"
     
       time_t tmt = time (NULL);
       struct tm t = *localtime(&tmt);
       char str[100];
     
       strftime (str, sizeof (str), "      Now = "FMT_DATE, &t);
       puts(str);
     
     
       t.tm_mday += 1; /* tomorrow */
       mktime (&t);
     
       strftime (str, sizeof (str), " Tomorrow = "FMT_DATE, &t);
       puts(str);
     
       t.tm_mday -= 2; /* yesterday */
       mktime (&t);
     
       strftime (str, sizeof (str), "Yerserday = "FMT_DATE, &t);
       puts(str);
     
       return 0;
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
          Now = 03/09/2007 19:49:09
     Tomorrow = 04/09/2007 19:49:09
    Yerserday = 02/09/2007 19:49:09
     
    Press ENTER to continue.
    Même si on change de mois, d'année etc, mktime() fait les ajustements nécessaires.

    EDIT : OK, j'ai compris le début de ton code. C'est pour simuler le cas du P.O. OK pour la conversion texte/struct tm. Mais pour le reste, il suffit de jouer sur les éléments de struct tm et faire confiance à mktime() pour tout remettre droit...
    Pas de Wi-Fi à la maison : CPL

  9. #9
    Rédacteur
    Avatar de Vincent Rogier
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    2 373
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 2 373
    Points : 5 307
    Points
    5 307
    Par défaut
    Citation Envoyé par Emmanuel Delahaye Voir le message
    Que c'est compliqué...
    Peut être mon exemple était plus compliqué, mais il peut gérer un diff de dates ou d'heures a cheval sur deux jours alors que le tiens ne le peut pas...

    Si tu veux retrancher 5 heures à une date/heures quelconque, ton code ne fonctionne pas..

    Et justement la problèmatique initial du post portait sur la différence de date/heure....
    Vincent Rogier.

    Rubrique ORACLE : Accueil - Forum - Tutoriels - FAQ - Livres - Blog

    Vous voulez contribuer à la rubrique Oracle ? Contactez la rubrique !

    OCILIB (C Driver for Oracle)

    Librairie C Open Source multi-plateformes pour accéder et manipuler des bases de données Oracle

  10. #10
    Membre éprouvé
    Avatar de Freed0
    Profil pro
    Étudiant
    Inscrit en
    Mars 2005
    Messages
    635
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2005
    Messages : 635
    Points : 953
    Points
    953
    Par défaut
    Citation Envoyé par vicenzo Voir le message
    Peut être mon exemple était plus compliqué, mais il peut gérer un diff de dates ou d'heures a cheval sur deux jours alors que le tiens ne le peut pas...

    Si tu veux retrancher 5 heures à une date/heures quelconque, ton code ne fonctionne pas..

    Et justement la problèmatique initial du post portait sur la différence de date/heure....
    Et pourtant son code est la meilleure solution à mon sens... Tu peux définir toi même la date en remplissant la structure manuellement. Ensuite tu manipules comme tu en as besoin.

  11. #11
    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 vicenzo Voir le message
    Peut être mon exemple était plus compliqué, mais il peut gérer un diff de dates ou d'heures a cheval sur deux jours alors que le tiens ne le peut pas...

    Si tu veux retrancher 5 heures à une date/heures quelconque, ton code ne fonctionne pas..
    Tu as essayé ?
    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
     
    #include <time.h>
    #include <stdio.h>
     
    int main (void)
    {
       #define FMT_DATE "%d/%m/%Y %H:%M:%S"
     
       time_t tmt = time (NULL);
       struct tm t = *localtime(&tmt);
       char str[100];
     
       strftime (str, sizeof (str), "          Now = "FMT_DATE, &t);
       puts(str);
     
     
       t.tm_mday += 1; /* tomorrow */
       mktime (&t);
     
       strftime (str, sizeof (str), "     Tomorrow = "FMT_DATE, &t);
       puts(str);
     
       t.tm_mday -=1;  /* today */
       t.tm_hour +=12; /* next 12 hours */
       mktime (&t);
     
       strftime (str, sizeof (str), "Next 12 hours = "FMT_DATE, &t);
       puts(str);
     
       t.tm_hour -=12; /* today */
       t.tm_hour -=12; /* prev 12 hours */
       mktime (&t);
     
       strftime (str, sizeof (str), "Prev 12 hours = "FMT_DATE, &t);
       puts(str);
     
       return 0;
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
              Now = 03/09/2007 20:26:14
         Tomorrow = 04/09/2007 20:26:14
    Next 12 hours = 04/09/2007 08:26:14
    Prev 12 hours = 03/09/2007 08:26:14
     
    Press ENTER to continue.
    Pas de Wi-Fi à la maison : CPL

  12. #12
    Rédacteur
    Avatar de Vincent Rogier
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    2 373
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 2 373
    Points : 5 307
    Points
    5 307
    Par défaut
    Citation Envoyé par Freed0 Voir le message
    Et pourtant son code est la meilleure solution à mon sens... Tu peux définir toi même la date en remplissant la structure manuellement. Ensuite tu manipules comme tu en as besoin.
    En quoi la solution d'emmanuel est la meilleure solution dans cas (diférence de dates) ? J'aimerai bien que tu me l'expliques !

    tu récuperes une date / heure. Tu veux ajouter 8 heures. Si tu veux manipuler la structure tm directement (solution d'Emmanuel), tu dois donc tester la valeur de tm_hour pour savoir si c'est > 23. Si oui, tu dois changer de jour, Ensuite si c'était un 30 ou un 31, tu dois changer de mois... etc...
    Que de tests !!!!
    alors que tu a un time_t avec lequel tu fais une diff en seule opération (ma solution)...

    Alors, Non à mon sens, sur un résultat équivalent, mon code est beaucoup plus simple ...
    Vincent Rogier.

    Rubrique ORACLE : Accueil - Forum - Tutoriels - FAQ - Livres - Blog

    Vous voulez contribuer à la rubrique Oracle ? Contactez la rubrique !

    OCILIB (C Driver for Oracle)

    Librairie C Open Source multi-plateformes pour accéder et manipuler des bases de données Oracle

  13. #13
    Rédacteur
    Avatar de Vincent Rogier
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    2 373
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 2 373
    Points : 5 307
    Points
    5 307
    Par défaut
    Citation Envoyé par Emmanuel Delahaye Voir le message
    Tu as essayé ?
    J'ai essayé ton code - j'ai ajouté 8 heures et non pas un jour et ca marche pas...
    Vincent Rogier.

    Rubrique ORACLE : Accueil - Forum - Tutoriels - FAQ - Livres - Blog

    Vous voulez contribuer à la rubrique Oracle ? Contactez la rubrique !

    OCILIB (C Driver for Oracle)

    Librairie C Open Source multi-plateformes pour accéder et manipuler des bases de données Oracle

  14. #14
    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 vicenzo Voir le message
    J'ai essayé ton code - j'ai ajouté 8 heures et non pas un jour et ca marche pas...
    Normal, j'avais oublié un mktime(). Essaye la version corrigée ou la nouvelle.

    Pourquoi tu ne lis pas la doc de mktime() ? C'est pas de la magie, le comportement est spécifié.
    Pas de Wi-Fi à la maison : CPL

  15. #15
    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 vicenzo Voir le message
    En quoi la solution d'emmanuel est la meilleure solution dans cas (diférence de dates) ? J'aimerai bien que tu me l'expliques !

    tu récuperes une date / heure. Tu veux ajouter 8 heures. Si tu veux manipuler la structure tm directement (solution d'Emmanuel), tu dois donc tester la valeur de tm_hour pour savoir si c'est > 23. Si oui, tu dois changer de jour, Ensuite si c'était un 30 ou un 31, tu dois changer de mois... etc...
    Que de tests !!!!
    Mais non. La seule chose à faire, c'est de ne pas oublier l'appel à mktime(). C'est lui qui refait tous les tests et les ajustements, c'est fait pour... (Mais c'est vrai que cette possibilité est peu connue et pas enseignée...)
    Pas de Wi-Fi à la maison : CPL

  16. #16
    Rédacteur
    Avatar de Vincent Rogier
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    2 373
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 2 373
    Points : 5 307
    Points
    5 307
    Par défaut
    Autant pour moi, je pensais que les modifications de mktime se bornaient à modifier les valeurs incohérentes...

    Je ne la pensais pas aussi pragmatique...
    Vincent Rogier.

    Rubrique ORACLE : Accueil - Forum - Tutoriels - FAQ - Livres - Blog

    Vous voulez contribuer à la rubrique Oracle ? Contactez la rubrique !

    OCILIB (C Driver for Oracle)

    Librairie C Open Source multi-plateformes pour accéder et manipuler des bases de données Oracle

Discussions similaires

  1. Réponses: 4
    Dernier message: 19/03/2008, 11h50
  2. Réponses: 6
    Dernier message: 11/04/2007, 16h54
  3. Extraire les semaines dans les dates
    Par LE CORRE dans le forum C
    Réponses: 4
    Dernier message: 22/02/2006, 12h34
  4. [SQL] problème avec les date et les group By
    Par Stef784ever dans le forum Langage SQL
    Réponses: 3
    Dernier message: 23/11/2004, 09h18

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