Différence entre deux dates en C

Je suis débutant en C.

  • Existe-t-il un type de données pour les dates?
  • En C, nous travaillons avec le temps, y en at-il aussi pour les dates?
  • Comment puis-je calculer la différence entre deux dates?

Existe-t-il un type de données pour les dates?

Non, type de données intégré en C , vous devez définir un type de données défini par l’utilisateur.

Comment puis-je calculer la différence entre deux dates?

Vous pouvez essayer ceci:

 struct dt { int dd; int mm; int yy; }; typedef dt date; 

Dans main (), vous devez déclarer trois variables pour les data type.
Dans l’exemple suivant la différence d’ today ,
par exemple, vous voulez prendre la différence entre la date du jour ( c_date ) et la date de naissance ( dob )

  date dob,c_date,today; if(c_date.dd>=dob.dd) today.dd = c_date.dd-dob.dd; else { c_date.dd+=30; c_date.mm-=1; today.dd = c_date.dd-dob.dd; } if(c_date.mm>=dob.mm) today.mm = c_date.mm-dob.mm; else { c_date.mm+=12; c_date.yy-=1; today.mm = c_date.dd-dob.mm; } today.yy = c_date.yy-dob.yy; 

today vous avez la différence entre deux dates.

Il existe une autre méthode: double difftime (time_t end, time_t beginning);
Lisez cette réponse:
1. Comment comparer deux horodatages au format «Mois Date hh: mm: ss»
2. Comment trouvez-vous la différence entre deux dates en heures, en C?

Oui, la bibliothèque standard C Time Library contient les structures et les fonctions que vous souhaitez. Vous pouvez utiliser struct tm pour stocker la date et le difftime afin d’obtenir la différence.

Existe-t-il un type de données pour les dates de sauvegarde?

Non, bien que pour les dates comsockets dans la plage “maintenant plus ou moins quelques décennies”, vous pouvez utiliser time_t ou struct tm contenant la date / heure à (par exemple) minuit le jour correspondant. Alternativement, vous pouvez rechercher un élément appelé “jour julien”: calculez-le et stockez-le dans le type entier que vous préférez.

Existe-t-il une bibliothèque pour C aussi?

Les fonctions standard se rapportent toutes à la date / heure plutôt qu’à de simples dates: localtime , gmtime , gmtime .

Comment puis-je calculer différent entre deux dates

Une fois que vous l’avez dans un time_t vous pouvez soustraire les deux et diviser par 86400. Attention, toutefois, étant donné que “l’heure locale de minuit” sur deux jours différents peut ne pas être un multiple exact de 24 heures d’intervalle en raison des modifications de l’heure d’été.

Si vous avez besoin d’un calendrier dépassant la plage time_t de votre implémentation, vous êtes autonome. Si time_t est de 64 bits, alors, c’est plus que l’âge de l’univers, mais si time_t est de 32 bits, ce n’est pas bon pour l’histoire. Ou la planification de la retraite, même. Les applications historiques ont de toute façon leurs propres exigences concernant les calendriers (calendrier julien, calendriers totalement indépendants de Grégorien).

Vous pouvez créer une struct nommée date ayant les champs suivants

 typedef struct { int day; int month; int year; }date; 

C’est juste un plan que vous voulez, maintenant, marquez et datez et travaillez en conséquence. Pour trouver la différence, écrivez une fonction qui prend la différence entre day month et year des deux variables.

Vous devez définir une structure de date:

 typedef struct date { int day; int month; int year; } Date; 

Et ensuite, définissez une simple méthode date_compare() :

 int date_compare(Date *date1, Date *date2) { if (date1->year != date2->year) return (date1->year - date2->year); if (date1->month != date2->month) return (date1->month - date2->month); return (date1->day - date2->day); } 

Les options standard de la bibliothèque C pour les dates et les heures sont plutôt médiocres et comportent de nombreuses mises en garde et limitations. Si possible, utilisez une bibliothèque telle que Gnome Lib qui fournit GDate et de nombreuses fonctions utiles de date et d’heure . Cela inclut g_date_days_between() pour obtenir le nombre de jours entre deux dates.

Le rest de cette réponse se limitera à la bibliothèque standard C, mais si vous n’êtes pas obligé de vous limiter à la norme, ne vous torturez pas. Les dates sont étonnamment difficiles.


Existe-t-il un type de données pour les dates?

struct tm va servir. Laissez simplement l’heure, les minutes et les secondes à 0.

Le moyen le plus simple de s’assurer que tous les champs de struct tm sont correctement remplis est d’utiliser strptime .

 struct tm date; strptime( "2017-03-21", "%F", &date ); puts( asctime(&date) ); // Mon Mar 21 00:00:00 2017 

Mais ce n’est pas un excellent moyen de stocker des dates. Il est préférable d’utiliser les jours juliens (voir ci-dessous).

En C, nous travaillons avec le temps, y en at-il aussi pour les dates?

Si vous faites référence à time_t , c’est également pour les dates. C’est le nombre de secondes depuis “l’époque” qui est 1970-01-01 00:00:00 UTC sur les systèmes POSIX, mais pas nécessairement d’autres. Malheureusement, sa plage de sécurité n’est que de 1970 à 2037, bien que toute version récente d’un système d’exploitation ait considérablement élargi cette plage.

Comment puis-je calculer la différence entre deux dates?

Cela dépend de ce que vous voulez. Si vous souhaitez difftime le nombre de secondes, vous pouvez convertir la struct tm en time_t aide de difftime , puis utiliser difftime , mais cela est limité à la plage de timeout de time_t .

 int main() { struct tm date1, date2; strptime( "2017-03-21", "%F", &date1 ); strptime( "2018-01-20", "%F", &date2 ); printf("%.0lf\n", difftime(mktime(&date1), mktime(&date2))); } 

Si vous voulez le nombre de jours, convertissez les dates en jours juliens , le nombre de jours depuis le 24 novembre 4714 av. J.-C., puis soustrayez. Bien que cela puisse paraître ridicule, cette formule relativement simple tire parti des cycles du calendrier et utilise uniquement des calculs entiers.

 // The formulas for a and m can be distilled down to these tables. int Julian_A[12] = { 1, 1, 0 }; int Julian_M[12] = { 10, 11, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; int julian_day( struct tm *date ) { int a = Julian_A[date->tm_mon]; int m = Julian_M[date->tm_mon]; int y = date->tm_year + 1900 + 4800 - a; return date->tm_mday + ((153*m + 2) / 5) + 365*y + y/4 - y/100 + y/400 - 32045; } int main() { struct tm date1, date2; strptime( "2017-03-21", "%F", &date1 ); strptime( "2018-01-20", "%F", &date2 ); // 305 days printf("%d days\n", julian_day(&date2) - julian_day(&date1)); } 

Il existe d’autres formules simples pour convertir entre les dates juliennes et les dates du calendrier.

Obtenir des différences en années, en mois et en jours est difficile en raison du nombre de jours dans un mois qui varie en fonction du mois et de l’année, et parce qu’il doit être normalisé. Par exemple, vous ne diriez pas 2 ans, -1 mois, 2 jours. Vous diriez 1 an, 11 mois, 29 jours (ou peut-être 28, dépend du mois). Pour cette raison, faites la maths en jours juliens autant que possible.

Pour avoir une idée de ce qui est impliqué, PHP l’implémente comme date_diff . Regardez la quantité de code C requirejse .

 /* Version 3 (better) Date Difference between the two dates in days like VBA function DateDiff("d", date1, date2) in case of Gregorian. Same basic principle you can translate in lot of other languages. This is complete C code with date validity control. */ #include void main(){ long d1,m1,y1,d2,m2,y2; printf("Enter first date day, month, year\n"); scanf("%d%d%d",&d1,&m1,&y1); printf("Enter second date day, month, year\n"); scanf("%d%d%d",&d2,&m2,&y2); if((IsValid(d1,m1,y1)==0)||(IsValid(d2,m2,y2)==0)){ printf("Invalid date detected\n"); }else{ d1=DatDif(d1,m1,y1,d2,m2,y2); printf("\n\n Date difference is %d days\n",d1); } }// end main long DatDif(d1,m1,y1,d2,m2,y2) { long suma; suma=rbdug(d2,m2,y2) - rbdug(d1,m1,y1); if(y1 != y2){ if(y1 < y2){ suma+=Godn(y1,y2); }else{ suma-=Godn(y2,y1); } } return(suma); }// end DatDif long Godn(yy1,yy2) { long jj,bb; bb=0; for(jj=yy1;jj2)) a+=1; return(a); }//end rbdug //date validity long IsValid(dd,mm,yy) { long v[13]; if((0 < mm) && (mm < 13)){ v[1] = 32; v[2] = 29; v[3] = 32; v[4] = 31; v[5] = 32; v[6] = 31; v[7] = 32; v[8] = 32; v[9] = 31; v[10]= 32; v[11]= 31; v[12]= 32; if(((((yy%400)==0)||((yy%100)!=0)) &&((yy%4)==0))) v[2]+=1; if((0 < dd) && (dd < v[mm])){ return(1); }else{ return(0); } }else{ return(0); } }//end IsValid 
 /* Version 4 ( 100 % correct): Proleptic Gregorian date difference in days. Date Difference between the two dates in days like VBA function DateDiff("d", date1, date2) and better (without limitations of DateDiff) in case of Gregorian. Same basic principle you can translate in lot of other languages. This is complete C code with date validity control. */ #include void main(){ long d1,m1,y1,d2,m2,y2; printf("Enter first date day, month, year\n"); scanf("%d%d%d",&d1,&m1,&y1); printf("Enter second date day, month, year\n"); scanf("%d%d%d",&d2,&m2,&y2); if((IsValid(d1,m1,y1)==0)||(IsValid(d2,m2,y2)==0)){ printf("Invalid date detected\n"); }else{ d1=DatDif(d1,m1,y1,d2,m2,y2); printf("\n\n Date difference is %d days\n",d1); } }// end main long DatDif(d1,m1,y1,d2,m2,y2) { long suma; suma=rbdug(d2,m2,y2) - rbdug(d1,m1,y1); if(y1 != y2){ if(y1 < y2){ suma+=Godn(y1,y2); }else{ suma-=Godn(y2,y1); } } return(suma); }// end DatDif long Godn(yy1,yy2) { long jj,bb; bb=0; for(jj=yy1;jj2)) a+=1; return(a); }//end rbdug //date validity long IsValid(dd,mm,yy) { long v[13]; if((0 < mm) && (mm < 13)){ v[1] = 32; v[2] = 29; v[3] = 32; v[4] = 31; v[5] = 32; v[6] = 31; v[7] = 32; v[8] = 32; v[9] = 31; v[10]= 32; v[11]= 31; v[12]= 32; if ((mm==2)&&(IsLeapG(yy)==1)) v[2]=30; if((0 < dd) && (dd < v[mm])){ return(1); }else{ return(0); } }else{ return(0); } }//end IsValid //is leap year in Gregorian long IsLeapG(yr){ if(((((yr%400)==0)||((yr%100)!=0))&&((yr%4)==0))){ return(1); }else{ return(0); } }//end IsLeapG