Calculer le nombre de jours entre deux dates

Midoszz -  
Dalfab Messages postés 706 Date d'inscription   Statut Membre Dernière intervention   -
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

Dalfab Messages postés 706 Date d'inscription   Statut Membre Dernière intervention   101
 
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
fiddy Messages postés 11069 Date d'inscription   Statut Contributeur Dernière intervention   1 846
 
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
0
paly2 Messages postés 254 Date d'inscription   Statut Membre Dernière intervention   25
 
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é !
0
paly2 Messages postés 254 Date d'inscription   Statut Membre Dernière intervention   25
 
Pardon, erreur dans ma macro:
#define ANNEE_BISSEXTILE(A) (!(A%4) && (A%100) || !(A%400))
0
fiddy Messages postés 11069 Date d'inscription   Statut Contributeur Dernière intervention   1 846 > paly2 Messages postés 254 Date d'inscription   Statut Membre Dernière intervention  
 
La version 1 est pourtant plus juste :-).
De plus, il est conseillé de toujours mettre le paramètre entre parenthèse dans une macro.
Exemple : (A)%4 && !((A)%100)...
0
paly2 Messages postés 254 Date d'inscription   Statut Membre Dernière intervention   25
 
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.
0
fiddy Messages postés 11069 Date d'inscription   Statut Contributeur Dernière intervention   1 846
 
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.
0
paly2 Messages postés 254 Date d'inscription   Statut Membre Dernière intervention   25
 
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 ;-)
0
paly2 Messages postés 254 Date d'inscription   Statut Membre Dernière intervention   25
 
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.)
0