Calculer le nombre de jours entre deux dates

[Fermé]
Signaler
-
Messages postés
580
Date d'inscription
dimanche 7 février 2016
Statut
Membre
Dernière intervention
14 septembre 2021
-
J'ai cherche une fonction qu'elle permet de calculer le nombre de jours entre deux dates "struct" !!

typedef struct date {
int jour;
int moi;
int annee;
};

int nombre_jour( date d1,date d2)
{
..
...
....
}

merci pour votre aide..
A voir également:

4 réponses

Messages postés
580
Date d'inscription
dimanche 7 février 2016
Statut
Membre
Dernière intervention
14 septembre 2021
79
Bonjour,

En un peu plus compact, on décale de 2 mois pour placer le 29 février en fin, la formule (m*306+5)/10 donne alors le nombre de jours cumulé des mois!
Et en utilisant le principe de la division entière on obtient un code illisible mais qui doit fonctionner.
int numero_jour( date d ) {
    int  m = (d.mois + 9) % 12;   // jan->10 fev->11 mar->0 ... dec->9
    int  a = d.annee - (m >= 10); // mais soustraire 1 an en jan et fev
    return 1461*a/4 - a/100 + a/400 + (m*306 + 5)/10 + d.jour;
}
inline int nombre_jours( date d1 , date d2 ) {
    return numero_jour(d2) - numero_jour(d1);
}
1
Merci

Quelques mots de remerciements seront grandement appréciés. Ajouter un commentaire

CCM 42854 internautes nous ont dit merci ce mois-ci

Messages postés
11066
Date d'inscription
samedi 5 mai 2007
Statut
Contributeur
Dernière intervention
18 octobre 2016
1 775
Bonjour,

Pourquoi enlever le "Bonjour" mis en place automatiquement ?

Pas de fonction prête à l'emploi.
Deux possibilités :
1 - tu stockes tes dates dans une structure time_t, tu utilises la fonction difftime() pour obtenir la différence en seconde et tu convertis en jour.

2 - tu te créés une fonction toi-même (je dirai une petite quinzaine de lignes environ).

Cdlt,

Google is your friend
Messages postés
254
Date d'inscription
vendredi 29 août 2014
Statut
Membre
Dernière intervention
15 février 2018
22
Fais surtout attention aux années bissextiles, à mon avis c'est la plus grosse difficulté. Le nombre de jours changeant des mois en est une aussi. Le reste devrait être simple à réaliser.

Ici une macro pour calculer les années bissextiles:
#define ANNEE_BISSEXTILE(A) ((A%4) && !(A%100) || (A%400))


La curiosité est une excellente qualité !
Messages postés
254
Date d'inscription
vendredi 29 août 2014
Statut
Membre
Dernière intervention
15 février 2018
22
La version 1 est pourtant plus juste :-).

??
Non la version 1 est fausse, la version 2 est juste. A%4 (par exemple) retourne 0 (faux) quand A est divisible par 4, et autre chose (vrai) quand A n'est pas divisible. Il faut donc faire un ! pour inverser le résultat.
Messages postés
11066
Date d'inscription
samedi 5 mai 2007
Statut
Contributeur
Dernière intervention
18 octobre 2016
1 775
Ah ah, bien vu. Je pensais en mode booléen et que A%4 renvoyait 1 si c'était divisible par 4. Tu as tout à fait raison :-).
En revanche, je maintiens pour l'usage des parenthèses autour du paramètre dans la macro.
Messages postés
254
Date d'inscription
vendredi 29 août 2014
Statut
Membre
Dernière intervention
15 février 2018
22
Je n'ai jamais entendu dire qu'il fallait mettre des parenthèses, et ce n'est pas écrit dans les standards C, où il est clairement indiqué que tous les paramètres de la replacement list seront remplacés par l'argument correspondant, sauf précédés par l'opérateur # (stringification) ou précédés ou suivis de l'opérateur ## (concaténation).

Sinon pour le problème de "penser en mode booléen", oui c'est ce qu'on fait naturellement quand on utilise le modulo pour tester si un nombre est divisible, c'est pour ça que j'ai aussi fait l'erreur la première fois ;-)
Messages postés
11066
Date d'inscription
samedi 5 mai 2007
Statut
Contributeur
Dernière intervention
18 octobre 2016
1 775
Attention, je n'ai pas dit que c'était une obligation. C'est juste un bon conseil !
Pour une fois, il y a pratiquement un consensus de la part de tous les acteurs : GNU, Microsoft, plusieurs forums, etc.
Quelques exemples : https://c.developpez.com/cours/bernard-cassagne/node104.php https://gcc.gnu.org/onlinedocs/cpp/Macro-Arguments.html#Macro-Arguments, https://docs.microsoft.com/en-us/cpp/preprocessor/hash-define-directive-c-cpp?redirectedfrom=MSDN&view=msvc-160&viewFallbackFrom=vs-2019

La raison sous-jacente est que si tu n'utilises pas les parenthèses, la macro devient fausse lorsque tu l'utilises comme suit : ANNEE_BISSEXTILE(X+Y). En effet, l'opérateur modulo est prioritaire sur l'addition. Donc, X ne fera pas partie du modulo.
Messages postés
254
Date d'inscription
vendredi 29 août 2014
Statut
Membre
Dernière intervention
15 février 2018
22
Ah oui, je n'avais pas pensé à ça !
Messages postés
254
Date d'inscription
vendredi 29 août 2014
Statut
Membre
Dernière intervention
15 février 2018
22
Voilà je me suis amusé à réaliser la fonction et ceci est ma solution ^^ (il me semble qu'elle fonctionne...)

#include <stdio.h>

#define ANNEE_BISSEXTILE(A) (!(A%4) && (A%100) || !(A%400))

typedef struct date {
	int jour;
	int mois;
	int annee;
} date; // Ne pas oublier ce deuxième "date", on est dans un typedef.

int nombre_jours( date d1,date d2)
{
	const int jours_mois[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
	int nb_jours = 0;
	int annee, mois;
	
	nb_jours += d2.jour - d1.jour; // Jours
	
	if (d1.annee == d2.annee) {
		for (mois = d1.mois ; mois < d2.mois ; mois++)
			nb_jours += (ANNEE_BISSEXTILE(d2.annee) && mois == 2) ? 29 : jours_mois[mois-1];
	} else {
		for (mois = d1.mois ; mois <= 12 ; mois++)
			nb_jours += (ANNEE_BISSEXTILE(d1.annee) && mois == 2) ? 29 : jours_mois[mois-1]; // Mois de d1
		for (mois = 1 ; mois < d2.mois ; mois++)
			nb_jours += (ANNEE_BISSEXTILE(d2.annee) && mois == 2) ? 29 : jours_mois[mois-1]; // Mois de d2
		for (annee = d1.annee+1 ; annee < d2.annee ; annee++)
			nb_jours += (ANNEE_BISSEXTILE(annee)) ? 366 : 365; // Années
	}
	
	return nb_jours;
}

int main(void) {
	date d1 = {17,03,2016}, d2 = {16,04,2017};
	int nb_jours = nombre_jours(d1, d2); // signifie nb_jours = d2 - d1. Libre à toi de changer l'ordre des paramètres.
	printf("Nombre de jours entre d2 et d1: %d\n", nb_jours);
	return 0;
}


Et bravo fiddy pour l'estimation la fonction fait exactement 15 lignes !! (Enfin il y a certainement moyen de faire une fonction plus petite.)