---
# System prepended metadata

title: Untitled

---

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;

}
