Comment savoir quel jour était-on à une telle date?

Soyez le premier à donner votre avis sur cette source.

Snippet vu 38 234 fois - Téléchargée 31 fois

Contenu du snippet

Ceci un simple code ( débutant ) -en mode console- pour savoir quel jour somme nous en fonction d'une certaine date.
Ce programme s'utilise soit en ligne de commande soit en mode "progressif" ( je sais pas comment on dis... )
Pour utiliser en mode commande la syntaxe est :
emplacement_de_l'exe <int jour> <int mois> <long int annee>

voilou !

Source / Exemple :


#include <stdio.h>
#include <stdlib.h>

//Ces deux macros sont utilisés pour faire un calcul, ce calcul est expliqué en bas.
#define f(annee, mois) ( ((mois) <= 2) ? ((annee) - 1) : (annee) )
#define g(mois) ( ((mois) <= 2) ? ((mois) + 13) : ((mois) + 1) )

//Définition de la structure date contenant trois membres : le jour, le mois, et l'annee.
struct date
{
    int jour;
    int mois;
    long int annee;
};

//Tableaux de pointeur vers char servant à l'affichage des jours.
const char *daysOfWeek[] = { "dimanche", "lundi", "mardi", "mercredi", "jeudi", "vendredi", "samedi" };

//Ce calcul est plus ou moins expliqué en bas, ainsi que la raison pour laquelle
//Deuxmacros sont utilisés au lieu d'une seule.
#define myCalculOfDay(d) (1461 * f(d.annee, d.mois) / 4 + 153 * g(d.mois) / 5 + d.jour)
#define myWhatDay(d_) ( (myCalculOfDay(d_) - 621049) % 7 )

//Fonction affichant le jour. Cette fonction ne prend aucun argument car elle
//est utiliséé si l'utilisateu n'utilie pas le programme en ligne de commande.
void whatday( void )
{
    struct date entry;
    printf("\nEntrez votre date ( jj/mm/aaaa ) : ");
    scanf("%2i/%2i/%4li", &(entry.jour), &(entry.mois), &(entry.annee));
    printf("\n\nLe %2i/%2i/%4li est un %s.\n\n", entry.jour, entry.mois, entry.annee,
daysOfWeek[myWhatDay(entry)]);
    exit(EXIT_SUCCESS);
}

//Voici la meme fonction que celle d'au dessus, mais avec un argument de type structure date
//Cette structure a pour caleur les trois arguments de la ligne de commande.
void whatday2( struct date d_ )
{
    printf("\n\nLe %2i/%2i/%4li est un %s.\n\n", d_.jour, d_.mois, d_.annee,
daysOfWeek[myWhatDay(d_)]);                                                   //Affichage du jour grace au tableau
    exit(EXIT_SUCCESS);
}

//Fonction main, gerant "l'interface" du programme.
int main (int argc, char *argv[])
{
//Si l'utilisateur n'utilise pas le programme en ligne de commande, argc a pour valeur 1.
if (argc == 1)
     whatday();                                  //Lancement de la fonction whatday
//Si l'utilisateur utilise le programme en mode ligne de commande correctement ( c'est à dire 3 arguments ) argc a pour valeur 4
else if (argc == 4)
{
     //Definition de la structure entry. Conversion des arguments de type char de la ligne de commande vers le type approprié
     // ( atoi -> char vers int          -           atol -> char vers long int )
     struct date entry = { entry.jour = atoi(argv[1]), entry.mois = atoi(argv[2]), entry.annee = atol(argv[3]) };
     whatday2( entry );                            //Lancement de la fonction whatday2 avec comme argument la structure prédéfini
}
//Dans les autres cas ( l'utilisateur a taper des arguments de ligne de commande, mais pas le bon nombre)
else
{
    //Affichage d'un message d'erreur approprié
     printf("\n\nErreur, nombre d'arguments incorrect !\n\nFormat 1 :  whatday <jj> <mm> <aaaa>\n");
     printf("Format 2 : whatday\n\n");
     //Exit du programme avec une valeur d'erreur
     exit(EXIT_FAILURE);
}

//Retour d'une valeur d'erreur
return EXIT_FAILURE;
//Cette valeur ne sera jamais utilisée car le programme quittera toujours avant.
}

/**********                            END                                *********/

Conclusion :


Voila!

Explication du calcul :
Il existe une formule pour calculer le nombre de jours séparant deux dates. Il sagit de calculer N pour chacune des deux dates et d'en calculer ensuite la différence. N se calcul de la maniere suivante :

N = 1461 * f(annee, mois) / 4 + 153 * g(mois) / 5 + jour

où :
f(annee, mois) renvoie annee - 1 si mois est inferieur ou egale a 2, sinon, renvoie annee.
et
g(mois) renvoie mois + 13 si mois est infereur ou egale a 2, sinon, renvoie mois + 1.

Si on prend la valeur N d'une date calculé comme ci dessus, qu'on lui soustrait 621 049 et qu'on garde le modulo 7 ( reste de la division de ce nombre par 7 ) on obtient une valeur comprise entre 0 et 6. Cette valeur correspond au jour de la semaine ( 1 -> lundi, donc 0 -> dimanche ).

Si j'ai donc ecris le calcul en deux macros, c'est pour pouvoir l'extraire plus facilement pour calculer la difference entre deux dates...
Maintenant que vous savez faire, vous pouvez vous aussi le faire.

PS : Cette formule a été trouvé dans un ouvrage sur le C intitulé "programmation en language C", de Stephen KOCHAN.

MERCI !

A voir également

Ajouter un commentaire

Commentaires

Karkanas
Messages postés
2
Date d'inscription
mardi 4 décembre 2012
Statut
Membre
Dernière intervention
9 avril 2014
-
Bonjour,

Je viens tout juste de consulter cet article, et aussi de m'inscrire.

Tout d'abord merci pour le post, je programme en Java mais les formules mathématiques restant bonnes quelque soit le langage, cela m'a bien aidé !!

KHIMI : Une année bissextiles c'est, (une année divisible par 4 ET NON par 100 OU une année divisible par 400).
khimi
Messages postés
4
Date d'inscription
samedi 3 novembre 2007
Statut
Membre
Dernière intervention
14 mai 2012
-
Je sais que cela fait un moment que ce code a été déposé, cependant je tiens à signaler que l'algorithme de calcul ne fonctionne pas correctement.
Il y un une erreur sur les années bissextiles, précisément sur les dates du 31 Janvier et du 1er Février qui retournent exactement le même numéro de jour.

J'ai testé avec les dates du 31/01/2012 et du 01/02/2012, et le calcul retourne le chiffre 3.
Voici comment j'ai résolu ce problème ( j'ai fait quelques tests afin de vérifier son exactitude, cependant il se peut qu'il soit lui aussi incorrect ) :

// Petite macro permettant de savoir si l'année est bissextile ou non, les années bissextiles doivent être divisibles par 4 et non divisible par 100
#define isLeapYear( year ) ( ( year % 4 == 0 ) && ( year % 100 != 0 ) )

Ensuite il suffit de modifier légèrement la macro g afin quelle prenne en compte les années bissextiles,
pour le mois de février des années bissextiles, il ne faut pas ajouter 13 mais 8 :
#define g( year, month ) ( month < 3 ? ( isLeapYear( year ) && month > 1 ? month + 8 : month + 13 ) : month + 1 )

En espérant vous avoir aidé.
bennoua34
Messages postés
1
Date d'inscription
jeudi 29 avril 2010
Statut
Membre
Dernière intervention
21 mai 2010
-
Super beau travail!
tekila_bandita
Messages postés
248
Date d'inscription
mercredi 15 juin 2005
Statut
Membre
Dernière intervention
15 mars 2007
6 -
Eh bien en faite, si on s'y attarde un peu je pense que l'on pourrait reussir a simplifier la formule, mais moi je l'ai trouver en tant qu'exercice d'application dans mon livre sur le C, alors je l'ai appliqué...
Dans l'exercice, il montre une formule que si on l'applique à deux dates et que l'on effectue la différence des resultats obtenus, alors on obtient, d'une maniere simple, le nombre de jours d'ecart entre ces deux dates...
Dans un exercice juste en dessous, il nous dise que si l'on reprend le resultat de ce calcul appliqué à une date, qu'on lui soustrait 621049 et qu'on garde le reste de ce resultat divisé par 7, on obtient un chiffre compris entre 0 et 6 indiquant le jour de la semaine (Le lundi étant le premier jour de la semaine, il se voit donc affecter la valeur 1, donc dimanche et 0 vu qu'il n'y a pas de valeur 7...)...

Je ne peus pas plus vous expliqué, mais si un jour je m'attarde sur cette formule, alors je vous ferait part des details du calcul...
En tout cas, merci pour vos notes ! :D ;)
cs_Joky
Messages postés
1787
Date d'inscription
lundi 22 novembre 2004
Statut
Membre
Dernière intervention
31 janvier 2009
2 -
Moi je fais comme ça :

int Julien(int Day, int Month, int Year)
{
int J;
J = 367*Year-7*(Year+(Month+9)/12)/4-3*((Year+(Month-9)/7)/100+1)/4+275*Month/9+Day+1721029;
J++;
return J;
}

int FindDay(char* MyDate)
{
char *Day[] = {"Dimanche", "Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi", "Samedi"};
int J = Julien(MyDate->Day, MyDate->Month, MyDate->Year);

strcpy(MyDate, Day[J%7]);
return J%7;
}

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.