// cDate.cpp Date du jour et quelques manipulations // > Cdate: une classe // > Date courante, jour, mois, année, heure, minute, seconde // > Nombre de jours entre deux dates, date n jours plus tard // > Année bissextile // > Calendriers d'un mois, d'une année // auteur: R.Astier // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + #include <time.h> #include <iostream> #include <strstream> using namespace std; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // fichier: cDate.h #ifndef CDATE_H #define CDATE_H typedef int tCalMois[6][7]; // calendrier mensuel typedef char tChCalMois[7][7][4]; // cal. mensuel: tableau de chaînes typedef char tChCalAnnee[4000]; // cal.annuel: une chaîne (des R/C) class cDate { public: // Noms des mois et des jours de la semaine static const char* mois[]; static const char* jours[]; // Instant présent (de l'appel) cDate () { instant=time(NULL); infos=*(localtime(&instant)); }; // Construction à partir d'un autre instant cDate (time_t i): instant(i){ infos=*(localtime(&instant)); }; // Construction à partir de jour,mois,année m=1 pour janvier // conditions: 1<=m<=12 ET 1900<=a cDate (int j, int m, int a); // Renvoie la date, exemple : ' jeudi 21 octobre 2004 (18:07:27)' // dans une zone statique (modifiée par un autre appel à zsDate()) char * cDate::zsDate(); // Renvoie la date, exemple : ' jeudi 21 octobre 2004 (18:07:27)' // indice(longueur) des champs: 0(8), 9(2), 12(9), 22(4), 28(2),31(2),34(2) // jour et mois peuvent commencer par des blancs string date() { return string(zsDate()); } // Nom du jour et mois, en chaîne const char* nomJour() { return jours[infos.tm_wday]; } const char* nomMois() { return mois[infos.tm_mon]; } // Jour, mois, année // avec 5/02/2005: j()=5; m()=2; a()=2005; qa()=23 int j() { return infos.tm_mday;} int m() { return 1+infos.tm_mon;} int a() { return 1900+infos.tm_year;} // Heure, minute, seconde int hh() { return infos.tm_hour;} int mm() { return infos.tm_min;} int ss() { return infos.tm_sec;} // Numéros du jour (0:dimanche), numéro du mois (0:janvier) // quantième dans l'année int nj() { return infos.tm_wday; } int nm() { return infos.tm_mon;} int qa() { return infos.tm_yday;} // Renvoie la cDate nbJours plus tard (sans changement d'heure) cDate jourPlusTard(int nbJours) { return cDate(instant+nbJours*JOUR); } // Renvoie le nombre n de jours entre les dates // n>0 si d2>cible; n<0 si cible<d2 int nJours(cDate d2); // Renvoie 1 si l'année de la cDate cible cours est bissextile int bissextile(); // Renvoie 1 si l'année a est bissextile // conditions: 1900<=a static int bissextile(int a); static int calendrierMois(int m, int a, tCalMois t, tChCalMois c=NULL); static void calendrierAnnee(int a, tCalMois t[12], tChCalAnnee c=NULL); private: time_t instant; struct tm infos; static const unsigned int JOUR=86400; /* champ de l'agrégat 'struc tm' dans time.h: struct tm* tmb = localtime(&instant); int j=tmb->tm_mday, // date dans le mois nj=tmb->tm_wday, // jour semaine 0:dimanche nm=tmb->tm_mon, // numéro du mois 0:janvier a=1900+tmb->tm_year, // année hh=tmb->tm_hour, // heure mm=tmb->tm_min, // minute ss=tmb->tm_sec, // seconde q=tmb->tm_yday; // quantième dans l'année */ }; const char* cDate::mois[]= { "janvier", "février", "mars","avril", "mai","juin","juillet","aout", "septembre","octobre","novembre","décembre"}; const char* cDate::jours[]={ "dimanche","lundi","mardi","mercredi", "jeudi", "vendredi","samedi"}; #endif // - - - - - - F i n d u f i c h i e r d ' e n t ê t e - - -+ // fichier: cDate.cpp // Construction à partir de jour,mois,année m=1 pour janvier // conditions: 1<=m<=12 ET 1900<=a cDate::cDate(int j, int m, int a) { memset(&infos,'\0',sizeof(infos)); // Tous les champs à 0 infos.tm_mday=j; infos.tm_mon=m-1; infos.tm_year=a-1900; instant = mktime(&infos); infos=*(localtime(&instant)); } // Renvoie la date, exemple : ' jeudi 21 octobre 2004 (18:07:27)' // dans une zone statique (modifiée par un autre appel à zsDate()) char * cDate::zsDate() { static char zs[80]; // struct tm* tmb = localtime(&instant); int j=infos.tm_mday, // date dans le mois nj=infos.tm_wday, // numéro jour semaine 0:dimanche nm=infos.tm_mon, // numéro du mois 0:janvier a=1900+infos.tm_year, // année hh=infos.tm_hour, // heure mm=infos.tm_min, // minute ss=infos.tm_sec; // seconde // int q=infos.tm_yday; // quantième dans l'année ostrstream da(zs,sizeof(zs)); da.setf(ios::right,ios::adjustfield); da.width(8); da << jours[nj] << " "; da.fill('0'); da.width(2); da<<j<< " "; da.fill(' '); da.width(9); da<<mois[nm]<< " "; da.fill('0'); da.width(4); da<<a<< " ("; da.width(2); da<<hh<< ":"; da.width(2); da<<mm<< ":"; da.width(2); da<<ss<< ")"; return zs; } //fin fonction char * cDate::zsDate() { // Renvoie le nombre de jours entre les dates int cDate::nJours(cDate dd) { if(dd.a()==a() && dd.nm()==nm() && dd.j()==j()) return 0; cDate d1=cDate(j(),1+nm(),a()), d2=cDate(dd.j(),1+dd.nm(),dd.a()); time_t delta=d2.instant-d1.instant; int apres=-1; if(d2.instant>d1.instant) apres=1; else delta=d1.instant-d2.instant; return apres*(delta/cDate::JOUR); } // int cDate::bissextile() { cDate dd(29,2,a()); return dd.j()==29; } int cDate::bissextile(int aa) { cDate dd(29,2,aa); // 29 février return dd.j()==29; // le quantième est-il 29? } // int cDate::calendrierMois(int m, int a, int t[6][7], char c[7][7][4]) { int nlt; // nb.lignes utilisées dans t cDate dm=cDate(1,m,a); // le premier du mois int ms,as; // mois suivant, et année if(m<12) { ms=m+1; as=a;} else { ms=1; as=a+1;} int njm=dm.nJours(cDate(1,ms,as)); // nombre de jours dans le mois int i,q, j=dm.nj(); if(j==0) j=6; else j--; // pour dimanche en dernière colonne for(q=0; q<j; q++) t[0][q]=0; // zeros avant le premier du mois i=0; j--; q=0; // avant incrémentation en début de boucle do { q++; if(j<6) j++; else { j=0; i++; } t[i][j]=q; } while(q<njm); nlt=i+1; // nombre de lignes remplies dans t // Compléter par des zéros for(j++; j<7; j++) t[i][j]=0; for(i++; i<6; i++) for(j=0; j<7; j++) t[i][j]=0; /* cout << "Calendrier "<<dm.nomMois()<<" "<<dm.a()<<endl; for(i=0; i<nlt; i++) { for(j=0; j<7; j++) { cout.width(4); if(t[i][j]) cout<<t[i][j]; else cout<<' '; } cout<<endl; } */ if(c==NULL) return nlt; // Tableau des jours char tj[][4]= {" Lu"," Ma"," Me"," Je"," Ve"," SA", " DI"}; for(j=0; j<7; j++) strcpy(c[0][j],tj[j]); for(i=1; i<7; i++) { for(j=0; j<7; j++) { strcpy(c[i][j]," "); q=t[i-1][j]; if(q>0) { if(q>9) c[i][j][1]='0'+q/10; // 2 chiffres c[i][j][2]='0'+q%10; // unité } } } return nlt; } // Fournit 12 tableaux des dates par mois sous forme numérique et une // chaîne void cDate::calendrierAnnee(int a, tCalMois t[12], tChCalAnnee c) { int m; for(m=1; m<13; m++) calendrierMois(m,a,t[m-1]); if(c==NULL) return; ostrstream fs(c,sizeof(tChCalAnnee)); int q, ia,ja,im,jm; char aSep[]=" | " ; char tj[][4]= {" Lu"," Ma"," Me"," Je"," Ve"," SA", " DI"}; for(im=1; im<13; im+=3) { // Noms des mois d'un trimestre for(jm=im; jm<im+3; jm++) { fs<<' '; fs.width(21); fs<<cDate::mois[jm-1]<<aSep; } fs<<"\n"; // En tête jours Lu Ma Me ... for(jm=im; jm<im+3; jm++) { for(ja=0; ja<7; ja++) { fs<<tj[ja]; if(ja==4) fs<<' '; } fs<<aSep; } fs<<"\n"; // Lignes des dates for(ia=0; ia<6; ia++) { // les trois mois du trimestre for(jm=im; jm<im+3; jm++) { for(ja=0; ja<7; ja++) { q=t[jm-1][ia][ja]; fs.width(3); if(q) fs<<q; else fs<<' '; if(ja==4) fs<<' '; } fs<<aSep; } fs<<"\n"; } fs<<"\n"; // séparation entre trimestres } fs<<ends; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // fichier: testDate.cpp // - - - - - - Q u e l q u e s u t i l i s a t i o n s - - - - - + int main( int ntm, char *tm[]) { // Construction cDate ud(29,2,2000); cout<<"Des dates"<<endl; cout << " 29_02_2000 '"<<ud.date()<<'\'' << endl; ud=cDate(29,12,2004); cout << " 29_12_2004 '"<<ud.date()<<'\'' << endl; /* Année bissextile cout<<"\nAnnées bissextiles ?"<<endl; cout << " bissextile 2004 ? "<<ud.bissextile()<< endl; cout << " bissextile 2000 ? "<<cDate(1,1,2000).bissextile()<< endl; cout << " bissextile 2003 ? "<<cDate::bissextile(2003)<< endl; ud=cDate(29,12,2004); */ // Instant actuel (date du jour) cDate maintenant=cDate(); // 24 heures plus tard cDate d=maintenant.jourPlusTard(1); // demain cout << "\ndemain : '" << d.date() <<'\'' << endl; cout << "\nmaintenant : '" << maintenant.date() <<'\'' << endl; // 61 jours avant, puis 13 jours plus tard, puis le lendemain d=maintenant.jourPlusTard(-61); cout << "61 jours avant: '" << d.date() <<'\'' << endl; d=d.jourPlusTard(13); cout << "13 jours apres: '" << d.date() <<'\'' <<endl; d=d.jourPlusTard(1); cout << "le lendemain : '" << d.zsDate() <<'\'' <<endl; // char * (chaîne C) renvoyée par la méthode zsDate() cout<<"\nlongueur chaine date:"<<strlen(d.zsDate())<<endl; // char * (chaîne C) renvoyée par la méthode date string dd=d.date(); cout<<"longueur chaine date:"<<dd.length()<< " an:"<<dd.substr(22,4)<<endl; /* Nombre de jours séparant deux dates int nbj; d=maintenant; nbj=maintenant.nJours(d); cout<<"attendu:0 obtenu:"<<nbj<<endl; d=cDate(maintenant.jourPlusTard(13)); nbj=maintenant.nJours(d); cout<<"attendu:13 obtenu:"<<nbj<<endl; d=cDate(maintenant.jourPlusTard(-13)); nbj=maintenant.nJours(d); cout<<"attendu:-13 obtenu:"<<nbj<<endl; d=cDate(maintenant.j()+1,maintenant.nm()+1,maintenant.a()); cout<<d.date()<<'-'<<maintenant.date()<<" "; nbj=maintenant.nJours(d); cout<<"attendu:1 obtenu:"<<nbj<<endl; d=cDate(maintenant.j(),maintenant.nm()+1,maintenant.a()); cout<<d.date()<<'-'<<maintenant.date()<<" "; nbj=maintenant.nJours(d); cout<<"attendu:0 obtenu:"<<nbj<<endl; d=cDate(maintenant.j()+5,maintenant.nm()+1,maintenant.a()); cout<<d.date()<<'-'<<maintenant.date()<<" "; nbj=maintenant.nJours(d); cout<<"attendu:5 obtenu:"<<nbj<<endl; d=cDate(maintenant.j()-1,maintenant.nm()+1,maintenant.a()); cout<<d.date()<<'-'<<maintenant.date()<<" "; nbj=maintenant.nJours(d); cout<<"attendu:-1 obtenu:"<<nbj<<endl; cout << endl; */ /* Calendier mensuel; tCalMois cal; int ic,jc,nlc; tChCalMois ccal; cDate dm; dm=cDate(1,1,2005); nlc=cDate::calendrierMois(dm.m(),dm.a(),cal,ccal); cout << "Calendrier "<<dm.nomMois()<<" "<<dm.a()<<endl; for(ic=0; ic<nlc+1; ic++) { for(jc=0; jc<7; jc++) cout<<ccal[ic][jc]; cout<<endl; } dm=cDate(1,2,2004); nlc=cDate::calendrierMois(dm.m(),dm.a(),cal,ccal); cout << "Calendrier "<<dm.nomMois()<<" "<<dm.a()<<endl; for(ic=0; ic<nlc+1; ic++) { for(jc=0; jc<7; jc++) cout<<ccal[ic][jc]; cout<<endl; } dm=cDate(1,3,2004); nlc=cDate::calendrierMois(dm.m(),dm.a(),cal,ccal); cout << "Calendrier "<<dm.nomMois()<<" "<<dm.a()<<endl; for(ic=0; ic<nlc+1; ic++) { for(jc=0; jc<7; jc++) cout<<ccal[ic][jc]; cout<<endl; } dm=cDate(1,7,2005); nlc=cDate::calendrierMois(dm.m(),dm.a(),cal,ccal); cout << "Calendrier "<<dm.nomMois()<<" "<<dm.a()<<endl; for(ic=0; ic<nlc+1; ic++) { for(jc=0; jc<7; jc++) cout<<ccal[ic][jc]; cout<<endl; } cout<<endl; */ /* Calendier annuel; tCalMois ca[12]; int annee, ia,ja,im,jm; char aSep[]=" | " ; char tj[][4]= {" Lu"," Ma"," Me"," Je"," Ve"," SA", " DI"}; annee=2004; cDate::calendrierAnnee(annee,ca); for(im=1; im<13; im+=3) { // Noms des mois d'un trimestre for(jm=im; jm<im+3; jm++) { cout<<' '; cout.width(21); cout<<cDate::mois[jm-1]<<aSep; } cout<<endl; // En tête jours Lu Ma Me ... for(jm=im; jm<im+3; jm++) { for(ja=0; ja<7; ja++) { cout<<tj[ja]; if(ja==4) cout<<' '; } cout<<aSep; } cout<<endl; // Lignes des dates for(ia=0; ia<6; ia++) { // les trois mois du trimestre for(jm=im; jm<im+3; jm++) { for(ja=0; ja<7; ja++) { cout.width(3); if(ca[jm-1][ia][ja]) cout<<ca[jm-1][ia][ja]; else cout<<' '; if(ja==4) cout<<' '; } cout<<aSep; } cout<<endl; } cout<<endl; // séparation entre trimestres } cout << endl; */ // Calendier annuel: tableau de caractères tCalMois cd[12]; int annee; tChCalAnnee chAnnee; annee=2005; cDate::calendrierAnnee(annee,cd,chAnnee); cout<<chAnnee<<endl; cout <<"longueur: "<<strlen(chAnnee)<<endl; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + cout<<"> > > "; cin.getline( new char[80],80); return 0; } //fin cDate.cpp