/home/manu/Dropbox/Projets/dates/main.cpp
#include <iostream>
#include <string.h>
#include <stdio.h>
using namespace std;

const char JOUR_SEMAINE[7][9] = {"lundi", "mardi", "mercredi", "jeudi", "vendredi", "samedi", "dimanche"};

struct Mois
{
    char nom[10];
    unsigned nombreDeJours;
};

const Mois MOIS[12] = {{"janvier", 31},
                       {"février", 28},
                       {"mars", 31},
                       {"avril", 30},
                       {"mai", 31},
                       {"juin", 30},
                       {"juillet", 31},
                       {"août", 31},
                       {"septembre", 30},
                       {"octobre", 31},
                       {"novembre", 30},
                       {"décembre", 31}};

struct Date
{
    unsigned jourSemaine, jourMois, joursAnnee, mois;
    int annee;
};


int main()
{
    char jourSemaine[9];
    char nomMois[10];
    Date aujourdhui;
    bool valide;

    cout << "ATTENTION, la correspondance du jour de la semaine"
         << " avec la date d'aujourd'hui ne sera pas vérifiée !" << endl;

    /*******************************************************************************************************
    * Saisie de la date du jour
    ********************************************************************************************************/
    do {
        cout << endl << "Saisissez la date d'aujourd'hui (ex : mardi 9 octobre 2012)" << endl << "Date = ";

        cin >> jourSemaine >> aujourdhui.jourMois >> nomMois >> aujourdhui.annee;

        valide = false;
        for (int jour=0; jour<7; jour++)
            if (strcmp(JOUR_SEMAINE[jour], jourSemaine) == 0)
            {
                aujourdhui.jourSemaine = jour;
                valide = true;
                break;
            }

        if (!valide)
        {
            cout << "Le jour de la semaine n'est pas valide !!!" << endl;
            continue;
        }

        valide = false;
        for (int mois=0; mois<12; mois++)
            if (strcmp(MOIS[mois].nom, nomMois) == 0)
            {
                aujourdhui.mois = mois;
                valide = true;
                break;
            }

        if (!valide)
        {
            cout << "Le mois n'est pas valide !!!" << endl;
            continue;
        }

        if (aujourdhui.jourMois > MOIS[aujourdhui.mois].nombreDeJours)
        {
            cout << "Le jour du mois n'est pas valide !" << endl;
            valide = false;
        }
        else cout << "Votre date est valide !" << endl;
    }
    while (!valide);

    // Calcul des jours déjà fait au cours de l'année   
    aujourdhui.joursAnnee = 0;
    for (unsigned mois=0; mois < aujourdhui.mois; mois++)
        aujourdhui.joursAnnee += MOIS[mois].nombreDeJours;
    aujourdhui.joursAnnee += aujourdhui.jourMois;

    //................... en tenant compte des années bissextiles
    if (((2000-aujourdhui.annee)%4)==0 && aujourdhui.mois>1) aujourdhui.joursAnnee++;
    cout << "Nombre de jours dans l'année = " << aujourdhui.joursAnnee << endl;

    /*******************************************************************************************************
    * Saisie de la date à rechercher
    ********************************************************************************************************/
    Date recherche;

    do {
        cout << endl << "Saisissez la date de recherche (ex : 18 juin 2003)" << endl << "Date = ";

        cin >> recherche.jourMois >> nomMois >> recherche.annee;

        valide = false;
        for (int mois=0; mois<12; mois++)
            if (strcmp(MOIS[mois].nom, nomMois) == 0)
            {
                recherche.mois = mois;
                valide = true;
                break;
            }

        if (!valide)
        {
            cout << "Le mois n'est pas valide !!!" << endl;
            continue;
        }

        if (recherche.jourMois > MOIS[recherche.mois].nombreDeJours)
        {
            cout << "Le jour du mois n'est pas valide !" << endl;
            valide = false;
        }
        else cout << "Votre date est valide !" << endl;
    }
    while (!valide);

    // Calcul des jours déjà fait au cours de l'année
    recherche.joursAnnee = 0;
    for (unsigned mois=0; mois < recherche.mois; mois++)
        recherche.joursAnnee += MOIS[mois].nombreDeJours;
    recherche.joursAnnee += recherche.jourMois;

    //................... en tenant compte des années bissextiles
    if (((2000-recherche.annee)%4)==0 && recherche.mois>1) recherche.joursAnnee++;
    cout << "Nombre de jours dans l'année = " << recherche.joursAnnee << endl;

    /*******************************************************************************************************
    * Calcul du jour de la semaine de la date à calculer par rapport à la date du jour.
    ********************************************************************************************************/
    int jours = 0;
    if (recherche.annee<=aujourdhui.annee) {
       for (int annee = recherche.annee; annee<aujourdhui.annee; annee++)
           jours += (annee-2000)%4 == 0 ? 366 : 365;
       int differenceDeJours = jours - recherche.joursAnnee + aujourdhui.joursAnnee;
       int decalageJour = differenceDeJours>0 ? 7-differenceDeJours%7 : -differenceDeJours%7;
       recherche.jourSemaine = (decalageJour+aujourdhui.jourSemaine)%7;
    }
    else {
       for (int annee = aujourdhui.annee; annee<recherche.annee; annee++)
          jours += (annee-2000)%4 == 0 ? 366 : 365;
       int differenceDeJours = jours + recherche.joursAnnee - aujourdhui.joursAnnee;
       recherche.jourSemaine = (differenceDeJours+aujourdhui.jourSemaine)%7;
    }

    cout << endl << "Le jour de la semaine est le " << JOUR_SEMAINE[recherche.jourSemaine] << endl << endl;

    return 0;
}