Programme calculant la difference entre 2 dates

Programme calculant la difference entre 2 dates - C - Programmation

Marsh Posté le 17-01-2007 à 12:35:05    

Bonjour a tous, je dois creer un programme en langage C qui se charge de calculer la difference entre 2 dates entr3ee au clavier (JJ MM AAAA).
Mon probleme est que je ne sais pas comment calculer cette difference compte tenu que tout les mois n'ont pas le meme nombre de jour et que les annee bysextiles comptent aussi.
 
Si quelqu'un aurait une suggestion cela m'aiderait beaucoup.  
 
D'avance merci

Reply

Marsh Posté le 17-01-2007 à 12:35:05   

Reply

Marsh Posté le 17-01-2007 à 13:05:17    

Deux méthodes :
 
- Soit avec des if. C'est relativement facile, même si c'est un peu fastidieux.
- Soit en utilisant les fonctions d'une bibliothèque.

Reply

Marsh Posté le 17-01-2007 à 13:10:22    

time_t


---------------
Töp of the plöp
Reply

Marsh Posté le 17-01-2007 à 13:13:52    

Regarde du côté des fonctions de time.h, je pense notamment au type de donnée "struct tm", et la fonction mktime() qui permet de convertir une telle structure en une valeur de type time_t, qui représente le nombre de secondes depuis The Epoch (01/01/1970).
 
Le but du jeu, c'est que si tu as deux dates représentées sous un nombre de secondes depuis une date fixe (ici, The Epoch), alors une simple soustraction te retourne une différence en secondes, facilement convertible.

Reply

Marsh Posté le 17-01-2007 à 15:51:31    

difftime

Reply

Marsh Posté le 17-01-2007 à 16:18:52    

USAGE
     The difftime() function is provided  because  there  are  no
     general arithmetic properties defined for type time_t.


 
(plus qu'à vérifier si j'ai pas des soustractions qui trainent dans mes programmes [:ciler] )

Reply

Marsh Posté le 17-01-2007 à 23:41:15    

ben tu fait un petite algo qui teste et calcule... ya rien de sorcier là dedans... faut faire travailler les méninges parfois... tout n'est pas dans les lib...

Reply

Marsh Posté le 18-01-2007 à 09:39:59    

Ange_blond a écrit :

ben tu fait un petite algo qui teste et calcule... ya rien de sorcier là dedans... faut faire travailler les méninges parfois... tout n'est pas dans les lib...


 [:bistou tt]

Reply

Marsh Posté le 18-01-2007 à 21:24:47    

tiens c'est un programme que j'ai fait dernièrement qui permettait de connaitre le jour de la semaine de ta date de naissance (y' une petite erreur que j'ai jamais corrigé, genre lors de l'an 1 mais sinon ça va te donner une petite idée de comment faire)
 
 

Code :
  1. #include <stdio.h>
  2. #include <conio.h>
  3. int bissextile (int aaaa)
  4. {
  5.     if (aaaa % 4 == 0 && (aaaa % 100 != 0 || aaaa % 400 == 0))
  6.         return 1;
  7.     else
  8.         return 0;
  9. }
  10. int date_correcte (int jj, int mm, int aaaa)
  11. {
  12.     int jj_aide;
  13.     switch (mm)
  14.     {
  15.         case 1: jj_aide = 31;
  16.             break;
  17.         case 2: if (bissextile (aaaa))
  18.                     jj_aide = 29;
  19.                 else
  20.                     jj_aide = 28;
  21.             break;
  22.         case 3: jj_aide = 31;
  23.             break;
  24.         case 4: jj_aide = 30;
  25.             break;
  26.         case 5: jj_aide = 31;
  27.             break;
  28.         case 6: jj_aide = 30;
  29.             break;
  30.         case 7: jj_aide = 31;
  31.             break;
  32.         case 8: jj_aide = 31;
  33.             break;
  34.         case 9: jj_aide = 30;
  35.             break;
  36.         case 10: jj_aide = 31;
  37.             break;
  38.         case 11: jj_aide = 30;
  39.             break;
  40.         case 12 : jj_aide = 31;
  41.             break;
  42.         default : return 0;
  43.     }
  44.     if (jj <= 0 || jj > jj_aide || aaaa  < 0)
  45.         return 0;
  46.     else
  47.         return 1;
  48. }
  49. void saisie_date (int *jj, int *mm, int *aaaa)
  50. {
  51.     do
  52.     {
  53.         printf ("\t\t\tEntrez la date (jj/mm/aaaa)\n\n\n" );
  54.         printf ("jj : " );
  55.         scanf ("%d", jj);
  56.         printf ("mm : " );
  57.         scanf ("%d", mm);
  58.         printf ("aaaa : " );
  59.         scanf ("%d", aaaa);
  60.     } while (!(date_correcte (*jj, *mm, *aaaa)));
  61. }
  62. long jours_ecoules (int jj, int mm, int aaaa)
  63. {
  64.     long compteur_jours, i;
  65.     compteur_jours = 0;
  66.     /* SOMME DES ANNEES */
  67.     for (i = 0; i < aaaa; i++)
  68.         if (bissextile (i))
  69.             compteur_jours+= 366;
  70.         else
  71.             compteur_jours+= 365;
  72.     /* SOMME DES JOURS DU MOIS COURANT */
  73.     compteur_jours+= jj;
  74.     /* SOMME DES JOURS DES MOIS RESTANT */
  75.     for (i = mm - 1; i > 0; i--)
  76.     {
  77.         switch (i)
  78.         {
  79.             case 1: compteur_jours+= 31;
  80.                 break;
  81.             case 2: if (bissextile (aaaa))
  82.                     compteur_jours+= 29;
  83.                 else
  84.                     compteur_jours+= 28;
  85.                 break;
  86.             case 3: compteur_jours+= 31;
  87.                 break;
  88.             case 4: compteur_jours+= 30;
  89.                 break;
  90.             case 5: compteur_jours+= 31;
  91.                 break;
  92.             case 6: compteur_jours+= 30;
  93.                 break;
  94.             case 7: compteur_jours+= 31;
  95.                 break;
  96.             case 8: compteur_jours+= 31;
  97.                 break;
  98.             case 9: compteur_jours+= 30;
  99.                 break;
  100.             case 10: compteur_jours+= 31;
  101.                 break;
  102.             default: compteur_jours+= 30;
  103.                 break;
  104.         }
  105.     }
  106.     return compteur_jours;
  107. }
  108. void jour_semaine (long nbre_jours)
  109. {
  110.     char *jours[] = {"Vendredi", "Samedi", "Dimanche", "Lundi", "Mardi", "Mercredi", "Jeudi"};
  111.     nbre_jours = (nbre_jours) % 7;
  112.     printf ("Le Jour de votre naissance est : %s", jours[nbre_jours]);
  113. }
  114. int main (void)
  115. {
  116.     int jj, mm, aaaa;
  117.     saisie_date (&jj, &mm, &aaaa);
  118.     jour_semaine (jours_ecoules (jj, mm, aaaa));
  119.     getch ();
  120.     return 0;
  121. }


 

Reply

Marsh Posté le 20-01-2007 à 21:37:48    

exhortae a écrit :


 
        case 3: jj_aide = 31;
            break;
        case 4: jj_aide = 30;
            break;
        case 5: jj_aide = 31;
            break;
        case 6: jj_aide = 30;
            break;
        case 7: jj_aide = 31;
            break;
.......
 


 
C'est quoi cette horreur ?

Reply

Marsh Posté le 20-01-2007 à 21:37:48   

Reply

Marsh Posté le 20-01-2007 à 21:49:00    

ca ressemble au nombre de jours dans le mois "i"

Reply

Marsh Posté le 20-01-2007 à 23:24:17    

exhortae a écrit :

tiens c'est un programme que j'ai fait dernièrement qui permettait de connaitre le jour de la semaine de ta date de naissance (y' une petite erreur que j'ai jamais corrigé, genre lors de l'an 1 mais sinon ça va te donner une petite idée de comment faire)


C'est bien compliqué. Pourquoi ne pas utiliser struct tm, mktime() etc ? C'est fait pour non ?


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 21-01-2007 à 09:37:05    

marctes a écrit :

C'est quoi cette horreur ?


 
Les case correspondent au mois, à chaque mois j'affecte à la variable aide son nombre de jours maximum (31 pour janvier...), puis je compare cette variable aide avec le nombre de jours entrés pour voir si il n'y a pas d'erreur dans le nombre de jours (genre je mets 31 pour avril alors qu'il n'en compte que 30)
 

Reply

Marsh Posté le 21-01-2007 à 10:29:02    

Emmanuel Delahaye a écrit :

C'est bien compliqué. Pourquoi ne pas utiliser struct tm, mktime() etc ? C'est fait pour non ?


 
 
Disons que le but c'était d'écrire la fonction sans rien utiliser de prédéfini, de plus si je ne me trompe pas mktime ne permet pas de connaitre le jour de naissance de christophe colomb ;), ma fonction si (à moins que je ne me trompe sur mktime )
 

Citation :


time_t mktime(struct tm *t);
 
Description
 
Converts time to calendar format.
The allowable range of calendar times is Jan 1 1970 00:00:00 to Jan 19 2038 03:14:07

Reply

Marsh Posté le 21-01-2007 à 14:54:45    

exhortae a écrit :

Les case correspondent au mois, à chaque mois j'affecte à la variable aide son nombre de jours maximum (31 pour janvier...), puis je compare cette variable aide avec le nombre de jours entrés pour voir si il n'y a pas d'erreur dans le nombre de jours (genre je mets 31 pour avril alors qu'il n'en compte que 30)


 

Code :
  1. ...
  2.     switch (mm)
  3.     {
  4.         case 1:
  5.         case 3:
  6.         case 5:
  7.         case 7:
  8.         case 8:
  9.         case 10:
  10.         case 12:
  11.             jj_aide = 31;
  12.             break;
  13.         case 4:
  14.         case 6:
  15.         case 9:
  16.         case 11:
  17.             jj_aide = 30;
  18.             break;
  19.         case 2:
  20.             jj_aide = bissextile(aaaa) ?29 :28;
  21.             break;
  22.     }
  23. ...

Message cité 2 fois
Message édité par Sve@r le 21-01-2007 à 14:55:23

---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le 21-01-2007 à 17:13:31    

Sve@r a écrit :

Code :
  1. ...
  2.     switch (mm)
  3.     {
  4. <...>
  5.     }
  6. ...



C'est beau. Dans mes délires,

 

http://mapage.noos.fr/emdel/clib/ed/src/date.c

 

je faisais ça :

Code :
  1. /* MONth TO Number Of Days */
  2. static int const Mon2nod[] =
  3. {
  4.    0
  5.    ,31                          /* Jan */
  6.    ,28                          /* Feb */
  7.    ,31                          /* Mar */
  8.    ,30                          /* Apr */
  9.    ,31                          /* May */
  10.    ,30                          /* Jun */
  11.    ,31                          /* Jul */
  12.    ,31                          /* Aug */
  13.    ,30                          /* Sep */
  14.    ,31                          /* Oct */
  15.    ,30                          /* Nov */
  16.    ,31                          /* Dec */
  17. };


Avec une correction sur le mois de février si nécessaire...

Message cité 1 fois
Message édité par Emmanuel Delahaye le 21-01-2007 à 17:15:14

---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 21-01-2007 à 17:26:51    

sinon on peut aussi s'amuser avec les modulo 2 et faire une correction pour le mois 2 et 7

Reply

Marsh Posté le 21-01-2007 à 17:59:13    

Sve@r a écrit :

Code :
  1. ...
  2.     switch (mm)
  3.     {
  4.         case 1:
  5.         case 3:
  6.         case 5:
  7.         case 7:
  8.         case 8:
  9.         case 10:
  10.         case 12:
  11.             jj_aide = 31;
  12.             break;
  13.         case 4:
  14.         case 6:
  15.         case 9:
  16.         case 11:
  17.             jj_aide = 30;
  18.             break;
  19.         case 2:
  20.             jj_aide = bissextile(aaaa) ?29 :28;
  21.             break;
  22.     }
  23. ...



 
j'y avais pas pensé, et ça augmente la lisibilité, merci

Reply

Marsh Posté le 21-01-2007 à 21:37:06    

Emmanuel Delahaye a écrit :

http://mapage.noos.fr/emdel/clib/ed/src/date.c

Code :
  1. static int is_leap (uint const year)
  2. {
  3.    return year % 4 == 0 && (year % 100 != 0 || year % 400 == 0);
  4. }



 
Etant donné qu'une année divisible par 400 est forcément divisible par 4, on peut optimiser un peu

Code :
  1. static int is_leap (uint const year)
  2. {
  3.    return (year % 4 == 0 && year % 100 != 0) || year % 400 == 0;
  4. }


 
D'une part ça évitera de distribuer le "et" sur les parenthèses, et d'autre part cela collera parfaitement avec la définition d'une année bissextile qui est:

  • divisible par 4 mais pas par 100

ou

  • divisible par 400

Message cité 1 fois
Message édité par Sve@r le 21-01-2007 à 21:43:08

---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le 21-01-2007 à 22:12:56    

Sve@r a écrit :

Etant donné qu'une année divisible par 400 est forcément divisible par 4, on peut optimiser un peu

Code :
  1. static int is_leap (uint const year)
  2. {
  3.    return (year % 4 == 0 && year % 100 != 0) || year % 400 == 0;
  4. }
 

D'une part ça évitera de distribuer le "et" sur les parenthèses, et d'autre part cela collera parfaitement avec la définition d'une année bissextile qui est:

  • divisible par 4 mais pas par 100

ou

  • divisible par 400


C'est assez discutable :
sur 400 années consécutives il y a :
1 année divisible par 400 (et donc par 4 et par 100) : 3 modtests
3 années divisibles par 100 et par 4 mais pas par  400 : 3 modtests
96 années divisibles par 4 seulement : 2 modtests
300 années indivisibles : 2 modtests

 

avec la méthode d'origine on a :

Code :
  1. return year % 4 == 0 && (year % 100 != 0 || year % 400 == 0);
 

1 année divisible par 400 (et donc par 4 et par 100) : 3 modtests
3 années divisibles par 100 et par 4 mais pas par  400 : 3 modtests
96 années divisibles par 4 seulement : 2 modtests
300 années indivisibles : 1 modtest

 

Le nombre de tests et modulos est identiques dans tout les cas sauf le plus courant (3/4 des cas), ou tu as perdu en efficacité en doublant le nombre de tests :/

 

(Oui c'est de la branlette :p)

 


Message cité 1 fois
Message édité par 0x90 le 21-01-2007 à 22:15:53

---------------
Me: Django Localization, Yogo Puzzle, Chrome Grapher, C++ Signals, Brainf*ck.
Reply

Marsh Posté le 22-01-2007 à 14:07:15    

0x90 a écrit :

C'est assez discutable :
sur 400 années consécutives il y a :
1 année divisible par 400 (et donc par 4 et par 100) : 3 modtests
3 années divisibles par 100 et par 4 mais pas par  400 : 3 modtests
96 années divisibles par 4 seulement : 2 modtests
300 années indivisibles : 2 modtests
 
avec la méthode d'origine on a :

Code :
  1. return year % 4 == 0 && (year % 100 != 0 || year % 400 == 0);


 
1 année divisible par 400 (et donc par 4 et par 100) : 3 modtests
3 années divisibles par 100 et par 4 mais pas par  400 : 3 modtests
96 années divisibles par 4 seulement : 2 modtests
300 années indivisibles : 1 modtest
 
Le nombre de tests et modulos est identiques dans tout les cas sauf le plus courant (3/4 des cas), ou tu as perdu en efficacité en doublant le nombre de tests :/
 
(Oui c'est de la branlette :p)


 
 
Très jolie démonstration.  :wahoo:  
On peut continuer un peu plus la branlette et examiner le cas où le compilo explose le test en redistribuant le "et" sur les parenthèses mais j'ai pas envie. Tu m'as convaincu !!!  :jap:


---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed