Wednesday, 25 April 2018

L'exercice de l'ecart entre deux dates

// *********************************************//
// La reutilisation de ce code est autorisée         //
// pour des fins pédagogiques non lucratives     //
// a condition de citer la ref :                                //
// (c) BouMen-Université de Boumerdes           //

// http://algocri18.blogspot.com                        //
// *********************************************//
#include <stdio.h>
#include <stdlib.h>
typedef struct {int jour,mois,annee;} tDate;

tDate nextDate(tDate);
void permutDate(tDate *date1, tDate *date2);
void affichDate(tDate date);
int date1AvtDate2(tDate date1,tDate date2);
int isBissextile(int annee);
int isDateValide(tDate date);

tDate date1,date2;

int main(){
    tDate tmpDate;int ecart=0;
    printf("Donner deux dates valides jj/mm/aaaa!\n");
    do{
       printf("Premiere date:");
    }while((scanf("%d/%d/%d",&date1.jour,&date1.mois,&date1.annee)!=3)||!isDateValide(date1));
    printf("  Ok\n");
    do{
       printf("\nDeuxieme date:");
    }while((scanf("%d/%d/%d",&date2.jour,&date2.mois,&date2.annee)!=3)||!isDateValide(date2));

    if(date1AvtDate2(date2,date1))permutDate(&date1,&date2);
    //methode efficace (chirurgicale)
    int vNbrJourMois[12]={31,28,31,30,31,30,31,31,30,31,30,31};
    int mois,annee;
    ecart+=vNbrJourMois[date1.mois-1]-date1.jour;
    for(mois=date1.mois+1;mois<=12;mois++)ecart+=vNbrJourMois[mois-1];
    ecart+=365*(date2.annee-date1.annee-1);
    for(mois=1;mois<date2.mois;mois++)ecart+=vNbrJourMois[mois-1];
    ecart+=date2.jour;
    for(annee=date1.annee+1;annee<date2.annee;annee++)if(isBissextile(annee))ecart++;

    printf("\nEcart 1:%d",ecart);

    //une autre méthode
    //int hejir=0; //en plus pour calculer l'age avec calend hejirien
    for(ecart=0,tmpDate=date1;date1AvtDate2(tmpDate,date2);ecart++,tmpDate=nextDate(tmpDate)){
       /*if(ecart%355==0){
         affichDate(tmpDate);
         printf("\t Hejir:%d",++hejir);
       }//sulp ne*/
    }


    printf("\nEcart 2:%d",ecart);
    return 0;
}

int isDateValide(tDate date)
{
    if((date.jour>31)||(date.jour<1)||(date.mois>12)||(date.mois<1)||(date.annee<1)) return 0;
    switch(date.mois)
    {
        case 4 :
        case 6 :
        case 9 :
        case 11 :if(date.jour>30) return 0; break;
        case 2 : if(date.jour>29)return 0;
                 if(!isBissextile(date.annee)&&(date.jour==29)) return 0;

    }
    return 1;
}

int isBissextile(int annee){
   return (((annee%4==0)&&(annee%100!=0))||(annee%400==0))?1:0;
}

tDate nextDate(tDate date){
  tDate dateSuiv=date;

  if((date.mois==2) && (date.jour==28)){
     if (isBissextile(date.annee)){dateSuiv.jour=29;dateSuiv.mois=2;}
     else {dateSuiv.jour=1;dateSuiv.mois=3;}
  }else if(((date.jour==30)&&((date.mois==4)||
                         (date.mois==6)||
                         (date.mois==9)||
                         (date.mois==11)))
        ||((date.jour==31)&&((date.mois==1)||
                         (date.mois==3)||
                         (date.mois==5)||
                         (date.mois==7)||
                         (date.mois==8)||
                         (date.mois==10)||
                         (date.mois==12)))||
        ((date.jour==29)&&(date.mois==2))){
        dateSuiv.jour=1;
        dateSuiv.mois++;
        if(date.mois==12){dateSuiv.annee++;dateSuiv.mois=1;}
     }else{
        dateSuiv.jour++;
  }
  return dateSuiv;
}
void permutDate(tDate *date1, tDate *date2){
   tDate tmpDate=*date1;*date1=*date2;*date2=tmpDate;
}
void affichDate(tDate date){
  printf("\ndate:%d/%d/%d",date.jour,date.mois,date.annee);
}
int date1AvtDate2(tDate date1,tDate date2){
   if(
        (date1.annee<date2.annee)||
        ((date1.annee==date2.annee)&&(date1.mois<date2.mois))||
        ((date1.annee==date2.annee)&&(date1.mois==date2.mois)&&(date1.jour<date2.jour))
    )return 1;
    else return 0;
}


Questions:
1. La méthode 1 marche t elle si les deux dates sont issues de la meme annee? Pourquoi?
2. Un peu de complexite (hors programme, mais essayer de reflechir quand meme): Quelle est la méthode la plus efficace (rapide)?
3. Si pour deux dates données, les deux ecarts sont différents faites le moi savoir please.

No comments:

Post a Comment

Note: only a member of this blog may post a comment.