/* pistes de solutions TP3 IUP2 décembre 2004 */
/* copyright P.TRAU 2004. L'utilisation de ce document sans mention de 
                                       son auteur constitue une fraude */

#include <iostream.h> 
#include <time.h> 

class date {
private:
 int jour,mois,an,heure,minute,seconde;
public:
 void saisir(void);
 void afficher(void);
 int comparer_a(date);
 void ajouter(int);
 void maintenant(void);
 int ecart(date);

//hors sujet, mais utile   
 int bissextile(void);    //dit si l'année est bissextile
 int longueur_mois(void); //dit combien on a de jours dans le mois actuel
 int valide(void);   //dit si la date est valide (affiche des messages si erreur)
};

void date::saisir(void)
{char c; //c contiendra le caractère de séparation, sans rien tester
 do{
   cout<<"entrez la date au format jj/mm/aaaa : ";
   cin>>jour>>c>>mois>>c>>an;
   cout<<"entrez l'heure au format hh:mn:ss : ";
   cin>>heure>>c>>minute>>c>>seconde;
   }
 while(!valide()); /*la vérification de la validité de la date entrée 
                                           n'était pas demandée dans le TP */
}
void date::afficher(void)
{
 cout<<"le "<<jour<<"/"<<mois<<"/"<<an;
 cout<<" a "<<heure<<":"<<minute<<":"<<seconde;
}
int date::comparer_a(date d)
{
 int r;
 if(d.an>an)r=1;
 else if(d.an<an)r=-1;
 else if(d.mois>mois)r=1;
 else if(d.mois<mois)r=-1;
 else if(d.jour>jour)r=1;
 else if(d.jour<jour)r=-1;
 else if(d.heure>heure)r=1;
 else if(d.heure<heure)r=-1;
 else if(d.minute>minute)r=1;
 else if(d.minute<minute)r=-1;
 else if(d.seconde>seconde)r=1;
 else if(d.seconde<seconde)r=-1;
 else r=0;
 return r;
}

int modulo(int &valeur, int pas)
//modifie valeur pour qu'il soit dans [0,pas[
//et retourne de combien de pas on a décalé (positif ou négatif) 
//cette fonction est uniquement la pour la méthode "ajouter"
{
 int rep;
 if(valeur>=pas)
  {
   rep=valeur/pas;
   valeur=valeur-(rep*pas);
   return rep;
  }
 else if (valeur<0)
  {
   rep=valeur/pas -1;
   valeur=valeur-(rep*pas);
   return rep;
  }
 else return 0;
}

void date::ajouter(int nbsecondes)
{
 int report;
 seconde+=nbsecondes;
 report=modulo(seconde,60); 
 minute+=report;
 report=modulo(minute,60);
 heure+=report;
 report=modulo(heure,24);
 jour+=report;
// là ça se corse sérieusement, on ne peut pas utiliser un modulo car les 
// longueurs de mois varient
 while(jour>longueur_mois())
  {
   jour-=longueur_mois();
   mois++;
   if(mois>12)
    {mois=1;an++;}
  }
 while(jour<1)
  {
   mois--;
   if(mois<1){mois=12;an--;}
   jour+=longueur_mois();
  }
}

int date::ecart(date d)
 {
  int e;
  e=(an-d.an)*365*24*3600;
  e+=(mois-d.mois)*30*24*3600; //il faudrait tenir compte des longueurs de mois
  e+=(jour-d.jour)*24*3600;
  e+=(heure-d.heure)*3600;
  e+=(minute-d.minute)*60;
  e+=(seconde-d.seconde);
  return e;
 }
 
int lng_mois[12]={31,28,31,30,31,30,31,31,30,31,30,31};
void date::maintenant(void)
{
 time_t t=time(NULL);
 seconde=t%60;
 t/=60;
 minute=t%60;
 t/=60;
 heure=t%24;
 t/=24;
 an=(t*4)/(365*4+1) + 1970;
 t-=(an-1970)*365;
 t-=(an-1970)/4; //pour année bissextile, marche jusqu'en 2100 au moins
 mois=0;
 while(t>lng_mois[mois]) {t-=lng_mois[mois];mois++;}
 mois++; //car on commence a 1, pas a 0
 jour=t;
}

int date::bissextile(void)
{
 return((an%4)==0); //retourne 0 ou 1
}
int date::longueur_mois(void)
{
 int l;
 l=lng_mois[mois-1];
 if(mois==2) l+=bissextile(); //ajoute 1 ou 0
 return l;
}
int date::valide(void) 
{
 int ok=1;
 if (seconde<0 || seconde>=60) 
  {cout<<"secondes invalides\n";ok=0;}
 if (minute<0 || minute>=60) 
  {cout<<"minutes invalides\n";ok=0;}
 if (heure<0 || heure>=24) 
  {cout<<"heure invalide\n";ok=0;}
 if (mois<=0 || mois>12)
  {cout<<"mois invalide\n";ok=0;}
 if(jour<0 || jour>longueur_mois())
  {cout<<"jour invalide\n";ok=0;}
 return ok;
}  

//surcharges des opérateurs
ostream& operator<< (ostream &f, date &d)
{d.afficher();return f;}
istream& operator>> (istream&f, date &d)
{d.saisir();return f;}
date operator+ (date d, int nbsec)
{
 date res;
 res=d;
 res.ajouter(nbsec);
 return res;
}
date operator- (date d, int nbsec)
{return d+(-nbsec);}
int operator== (date &d1, date &d2)
{return d1.comparer_a(d2)==0;}
int operator!= (date &d1, date &d2)
{return d1.comparer_a(d2)!=0;}
int operator< (date &d1, date &d2)
{return d1.comparer_a(d2)>0;}
int operator<= (date &d1, date &d2)
{return d1.comparer_a(d2)>=0;}
int operator> (date &d1, date &d2)
{return d1.comparer_a(d2)<0;}
int operator>= (date &d1, date &d2)
{return d1.comparer_a(d2)<0;}

int main(void) 
{
 date actu,reveil,plus5mn,tmp,chrono;
 char choix;
 int al=0,chr=0;
 int reglage=0;
 do
 { 
  actu.maintenant();
  actu=actu+reglage;
  cout<<"nous sommes "<<actu<<"\n";
  if(al)cout<<"A réveil prévu "<<reveil<<"\n";
  if(al && (actu>=reveil) && (actu<=plus5mn)) cout<<
                     "A DRING!!!!!!!!!!!!!!!!!!!!!!!!\n";
  if(chr)cout<<actu.ecart(chrono)<<"s écoulées\n";
  cout<<"choix q=quitte, f=fixe réveil, a=marche/arrêt réveil r=réglage t=chrono";
  cin>>choix;
  if(choix=='f')
    {reveil.saisir();
     al=1;
     plus5mn=reveil;
     plus5mn.ajouter(5*60);
     cout<<"on arête la sonnerie le ";plus5mn.afficher();cout<<endl;
    }
  else if(choix=='a') al=(-al)+1; //ou !al
  else if(choix=='r')
    {
     tmp.saisir();
     reglage=tmp.ecart(actu);
    }
  else if(choix=='t')
    {
     chr=!chr;
     if(chr) chrono=actu;
    }
 }
 while(choix!='q');
}  


retour tp4

(c) P. TRAU IPST - ULP decembre 2004