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; }