EXO2 Dates
```cpp
#include <stdexcept>
#include<iostream>
#include<iomanip>
using namespace std;
#define DOCTEST_CONFIG_IMPLEMENT
#include "doctest.h"
TEST_SUITE_BEGIN("Structure Date");
struct Date {
int jour, mois, annee;
};
/** Surcharge de << pour afficher une Date sous le format jj/mm/aaaa
* @param[in] d : Date
**/
std::ostream& operator<< (std::ostream &out, Date d) {
out << setfill('0') << setw(2) << d.jour << "/"
<< setfill('0') << setw(2) << d.mois << "/" << d.annee;
return out;
}
/** Surcharge de == pour verifier que deux dates d1 et d2 sont egales
* @param[in] d1 : Date
* @param[in] d2 : Date
* @return le booléen correspondant au test
**/
bool operator==(Date d1, Date d2) {
return d1.jour == d2.jour and d1.mois == d2.mois and d1.annee == d2.annee;
}
/** Surcharge de != pour verifier que deux dates d1 et d2 sont differentes
* @param[in] d1 : Date
* @param[in] d2 : Date
* @return le booléen correspondant au test
**/
bool operator!=(Date d1, Date d2) {
return not (d1 == d2);
}
TEST_CASE("surcharge == et !=") {
CHECK(Date{1, 1, 2000} == Date{1, 1, 2000});
CHECK(Date{2, 5, 2021} != Date{6, 8, 2020});
CHECK(Date{31, 12, 2020} != Date{1, 1, 2021});
CHECK((Date{14, 7, 2021} == Date{14, 7, 2021}));
CHECK((Date{14, 2, 1994} == Date{14, 2, 1994}));
CHECK((Date{1, 1, 2000} != Date{10, 1, 2000}));
CHECK((Date{1, 1, 2000} != Date{1, 1, 2020}));
}
/** Verifie si une année est bissextile
* @param[in] annee : un entier
* @return le booléen correspondant au test
**/
bool estBissextile(int annee) {
return (annee % 4 == 0 and annee % 100 != 0) or (annee % 400 == 0);
}
TEST_CASE("fonction estBissextile") {
CHECK(estBissextile(2000)==true);
CHECK(estBissextile(2020) == true);
CHECK(estBissextile(40) == true);
CHECK(estBissextile(2021) == false);
CHECK(estBissextile(1900) == false);
}
/** Le nombre de jours qu'il y a dans un mois
* @param[in] annee : un entier
* @param[in] mois : un entier entre 1 et 12
* @return le nombre de jours du mois
**/
int nbJourMois(int mois, int annee) {
switch (mois) {
case 1 : case 3 : case 5 :
case 7 : case 8 : case 10 : case 12 : return 31;
case 4 : case 6 : case 9 : case 11 : return 30;
case 2 :
if (estBissextile(annee)) return 29;
else return 28;
default: return -1;
}
}
TEST_CASE("fonction nbJourMois") {
CHECK(nbJourMois(2, 2000) == 29);
CHECK(nbJourMois(6, 2020) == 30);
CHECK(nbJourMois(12, 2021) == 31);
CHECK(nbJourMois(2, 1900) == 28);
CHECK(nbJourMois(2, 2001) == 28); // exemple volontairement faux
}
/** Verifie si une Date est correcte
* @param[in] d : une Date
* @return le booléen correspondant au test
**/
bool estCorrecteDate(Date d) {
if (d.mois <= 0 or d.mois > 12) return false;
if (d.jour <= 0) return false;
return d.jour <= nbJourMois(d.mois, d.annee);
}
/** Surcharge de >> pour lire une Date
**/
std::istream& operator>> (std::istream &in, Date &d) {
bool erreur;
do {
cout << "Donner jour mois annee" << endl;
in >> d.jour >> d.mois >> d.annee;
erreur = not estCorrecteDate(d);
if (erreur) cout << "Date incorrecte !" << endl;
} while (erreur);
return in;
}
/** Lendemain d'une Date
* @param[in] d : une date
**/
Date lendemain(Date d) {
d.jour++;
if (d.jour > nbJourMois(d.mois, d.annee)) {
d.jour = 1;
d.mois++;
if (d.mois == 13) {
d.mois = 1;
d.annee++;
}
}
return d;
}
/** Surcharge de < pour verifier si une date d1 est avant une date d2
* @param[in] d1 : Date
* @param[in] d2 : Date
* @return le booléen correspondant au test
**/
bool operator<(Date d1, Date d2) {
if (d1.annee < d2.annee) return true;
if (d1.annee == d2.annee) {
if (d1.mois < d2.mois) return true;
if (d1.mois == d2.mois) {
if (d1.jour < d2.jour) return true;
}
}
return false;
}
TEST_CASE("surcharge <") {
CHECK_FALSE(Date{1, 1, 2000} < Date{1, 1, 1999});
CHECK((Date{14, 7, 2021} < Date{15, 7, 2021}) == true);
CHECK_FALSE(Date{14, 2, 1994} < Date{14, 1, 1994});
CHECK((Date{1, 1, 2000} < Date{10, 2, 2000}) == true);
}
Date operator+(Date d, int n){
// Remplacer la ligne suivante par le code adéquat
throw runtime_error("code non implanté ligne 145");
}
TEST_CASE("Operateur + ") {
CHECK((Date{1, 1, 2000} + 8) == Date{9, 1, 2000});
// Remplacer la ligne suivante par le code adéquat
throw runtime_error("code non implanté ligne 151");
}
int operator-(Date d1, Date d2){
// Remplacer la ligne suivante par le code adéquat
throw runtime_error("code non implanté ligne 156");
}
TEST_CASE("Operateur - ") {
CHECK((Date{1, 1, 2000} - Date{1, 1, 2001}) == 366);
// Remplacer la ligne suivante par le code adéquat
throw runtime_error("code non implanté ligne 162");
}
int jourDate(Date d){
int diffJour = d - Date{1, 1, 2000};
int resteDelaDivision = diffJour % 7;
switch(resteDelaDivision){
case 0 : return 5; //"samedi";
case 1: return 6; //"dimanche";
case 2: return 0; //"lundi";
case 3: return 1; //"Mardi";
case 4: return 2; //"Mercredi";
case 5: return 3; //"Jeudi";
case 6: return 4; //"Vendredi";
default: return -1;
}
}
TEST_CASE("fonction jourDate") {
CHECK(jourDate({1, 1, 2000}) == 5 );
// Remplacer la ligne suivante par le code adéquat
throw runtime_error("code non implanté ligne 183");
}
TEST_SUITE_END();
int main(int argc, const char** argv) {
doctest::Context context(argc, argv);
int test_result = context.run();
if (context.shouldExit()) return test_result;
Date aujourdhui;
cin >> aujourdhui;
cout << "Aujoud'hui : ";
cout << aujourdhui;
cout << endl;
Date demain = lendemain(aujourdhui);
cout << "Demain : ";
cout << demain;
cout << endl;
int n = 8;
cout << "dans " << n << " jours c'est: ";
cout << aujourdhui+n;
cout << endl;
}