Duree - calcule la duree précise qui s'est écoulée entre 2 dates

Soyez le premier à donner votre avis sur cette source.

Vue 15 064 fois - Téléchargée 382 fois

Description

Un script qui calcule précisement la durée qui s'est écoulée entre 2 dates(il fait attention aux années bissextiles). Il dispose d'une fonction facilement réutilisable et documentée.

Source / Exemple :


<html>
<head>
<title>Iwaweb - Durée</title>
<script language="javascript">
erreur=0;
function calculduree(jourdebut,moisdebut,anneedebut,jourfin,moisfin,anneefin)
{
	//préconditions : jourdebut,moisdebut,anneedebut,jourfin,moisfin,anneefin sont des entiers et ont été initialisé correctement(c.a.d que la date de debut doit être inferieur à la date de fin)
	//postconditions : retourne un entier qui indique la durée en jour
	//explications : cette fonction est le coeur du script, c'est elle qui calcule la durée, et c'est cette fonction qu'il vous sera utile de réutiliser, cette fonction renvoie
	//la durée précise qui s'est écoulée, elle ne fait pas d'approximation et vérifie si l'année est bissextile
	

	function calcul_longueur_mois(annee)
	{
		//préconditions : annee est en entier
		//postconditions : retourne un tableau de 12 éléments d'entier qui indique le nombre de jours dans chaque mois

		var longueurmois=[31,28,31,30,31,30,31,31,30,30,30,31];
		if((!(annee % 4) && (annee % 100)) || !(annee % 400)) //vérifie si l'année traitée est bissextile
		{
			longueurmois=[31,28,31,30,31,30,31,31,30,30,30,31];		
		}
		return longueurmois;
		
	}
		
	var duree=0;
	for(i=anneedebut;i<anneefin;i++)
	{
		if((!(i % 4) && (i % 100)) || !(i % 400)) //vérifie si l'année traitée est bissextile
		{
			duree+=366;
		}
		else
		{
			duree+=365;
		}
	}
	var longueurmois=calcul_longueur_mois(anneedebut);
	for(i=0;i<moisdebut;i++)
	{
		if(i==moisdebut-1){duree-=jourdebut}
		else{duree-=longueurmois[i]}
	}
	
	var longueurmois=calcul_longueur_mois(anneefin);
	for(i=0;i<moisfin;i++)
	{
		if(i==moisfin-1){duree+=jourfin}
		else{duree+=longueurmois[i]}
	}
	return duree;
}
		

function verifierlongueur(champ)
{
	if(document.form1.elements[champ].value.length>10)
	{
		document.form1.elements[champ].value=document.form1.elements[champ].value.substring(0,10);
	}
}
function verifier(champ)
{
	message_erreur="Erreur(s) trouvée(s) dans le champ";

	if(champ){message_erreur+=" date de fin :\n"}
	else{message_erreur+=" date de début :\n"}

	verifierlongueur(champ);
	if(document.form1.elements[champ].value.length!=10)
	{
		erreur=1;
		message_erreur+="\nLa date que vous avez saisie ne respecte pas la forme jj/mm/aaaa !";
	}
	else
	{
		if(document.form1.elements[champ].value.substring(2,3)!="/" || document.form1.elements[champ].value.substring(5,6)!="/")
		{
			erreur=1;
			message_erreur+="\nLa date que vous avez saisie ne respecte pas la forme jj/mm/aaaa !";
		}
		else
		{
			jourok=0;
			for(i=1;i<32;i++)
			{
				jour=i.toString();
				if(i<10)
				{
					jour="0"+i;
				}
				if(jour==document.form1.elements[champ].value.substring(0,2))
				{
					jourok=1;									
				}
			}
			if(jourok)
			{
				moisok=0;
				for(i=1;i<13;i++)
				{
					mois=i.toString();
					if(i<10)
					{
						mois="0"+i;
					}
					if(mois==document.form1.elements[champ].value.substring(3,5))
					{
						moisok=1;											
					}
				}
				if(moisok)
				{
					if(isNaN(parseInt(document.form1.elements[champ].value.substring(6,10),10)))
					{
						erreur=1;
						message_erreur+="\nLa date que vous avez saisie contient une année non valide";
					}
					else
					{
						longueurmois=new Array();	
						jour=parseInt(document.form1.elements[champ].value.substring(0,2),10);
						mois=parseInt(document.form1.elements[champ].value.substring(3,5),10);
						annee=parseInt(document.form1.elements[champ].value.substring(6,10),10);
						if((!(annee % 4) && (annee % 100)) || !(annee % 400))
						{
							longueurmois=[31,29,31,30,31,30,31,31,30,31,30,31];
						}
						else
						{
							longueurmois=[31,28,31,30,31,30,31,31,30,31,30,31];
						}
						if(jour>longueurmois[mois-1])
						{
							erreur=1;
							message_erreur+="\nLa date que vous avez saisie n'existe pas !";
						}
					}
				}
				else
				{
					erreur=1;
					message_erreur+="\nLa date que vous avez saisie contient un mois non valide";
				}
					
			}
			else
			{
				erreur=1;
				message_erreur+="\nLa date que vous avez saisie contient un jour non valide";
			}
		}
	}
	if(erreur)
	{
		alert(message_erreur);
	}	
}
function ordredate()
{
	message_erreur="La date de début commence après la date de fin !";
	jourdebut=parseInt(document.form1.elements[0].value.substring(0,2),10);
	moisdebut=parseInt(document.form1.elements[0].value.substring(3,5),10);
	anneedebut=parseInt(document.form1.elements[0].value.substring(6,10),10);
	jourfin=parseInt(document.form1.elements[1].value.substring(0,2),10);
	moisfin=parseInt(document.form1.elements[1].value.substring(3,5),10);
	anneefin=parseInt(document.form1.elements[1].value.substring(6,10),10);
	if(!erreur)
	{
		if(anneedebut>anneefin){erreur=1;alert(message_erreur)}
		else
		{
			if(moisdebut>moisfin && anneedebut==anneefin){erreur=1;alert(message_erreur)}
			else
			{
				if(jourdebut>jourfin && anneedebut==anneefin && moisdebut==moisfin){erreur=1;alert(message_erreur)}
			}	
		}	
	}
	if(!erreur)
	{
		nbjour=calculduree(jourdebut,moisdebut,anneedebut,jourfin,moisfin,anneefin);
		alert("Entre le "+jourdebut+"/"+moisdebut+"/"+anneedebut+" et le "+jourfin+"/"+moisfin+"/"+anneefin+" il s'est écoulé :\n\n environ "+Math.ceil(nbjour/7)+" semaine(s) \nsoit "+nbjour+" jour(s)\nou "+nbjour*24+" heure(s)\n ou "+nbjour*1440+" minute(s)\nou si vous préférez "+ nbjour*86400 +" seconde(s).");
	}	
}
</script>
</head>
<body>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<blockquote>
  <p><font face="verdana" size="2"> Ce script va vous permettre de calculer la 
    durée exacte qui s'est écoulée entre 2 dates.<br>
    La date doit être sous la forme suivante : jj/mm/aaaa <br>
    <br>
    </font></p>
</blockquote>
<form name="form1">
  <blockquote>
    <p><font face="verdana" size="2"> Date de début :<br>
      <input type="text" name="datedebut" size="10" onchange="verifierlongueur(0)">
      <br>
      <br>
      Date de fin :<br>
      <input type="text" name="datefin" size="10" onchange="verifierlongueur(1)">
      <br>
      <br>
      <input type="button" value="Calculer" onclick="verifier(0);verifier(1);ordredate();erreur=0;">
      </font> </p>
  </blockquote>
</form>
</body>
</html>

Conclusion :


Retrouvez d'autres scripts sur Iwaweb : http://www.iwaweb.net

Mise à jour effectuée le 05/09/2003 : très gros bugs constatés(la version fournie sur javascriptfr était une vieille version buggée ) : ils sont normalement corrigés(merci de me le confirmer).

Codes Sources

A voir également

Ajouter un commentaire

Commentaires

cs_hubert75
Messages postés
1
Date d'inscription
mercredi 16 février 2005
Statut
Membre
Dernière intervention
1 avril 2006

Bonjour,

merci et bravo pour ce script. J'ai cependant remarqué une petite anomalie.
A partir du moment où on a fait une erreur de saisie, exemple j/m/aa, le message d'alerte apparaît bien, on corrige la date dans le format jj/mm/aaaa mais le message d'erreur apparaît toujours.
Il n'y a visiblement pas de réinitialisation des erreurs.
Enfin, ce serait peut-être bien de redonner le focus au champ qui n'est pas valide.
J'ai testé sous IE et sous firefox.

Pour mon usage perso ça va faire l'affaire.
cs_reblochon
Messages postés
49
Date d'inscription
lundi 28 avril 2003
Statut
Membre
Dernière intervention
27 septembre 2004

Pour finir:

Elle est moins precise car tes arguments de fonction sont:
function calculduree(jourdebut,moisdebut,anneedebut,jourfin,moisfin,anneefin) et donc limités à cela.

Avec la methode que je te montre tu envois deux objet date. Ton objet date peut etre simple new Date(2003,9,21) 21octobre 2003
ou plus precise new Date(2003,9,21,18,30) 21octobre 2003 à 18h30.

Il n'y a pas de limitation pour connaitre tout type d'ecart entre deux dates.

Quand tantot je parlais de milisecondes, ce n'etait pas pour me rendre plus malin que toi, mais c'est ce que retourne la soustraction entre deux objets Date().

Au revoir
Philippe
iwaweb
Messages postés
56
Date d'inscription
dimanche 22 octobre 2000
Statut
Membre
Dernière intervention
14 décembre 2017

Ah bon, la mienne est moins précise ? je vois mal pourquoi. Pas besoin de travailler avec des millisecondes pour avoir de la précision.
cs_reblochon
Messages postés
49
Date d'inscription
lundi 28 avril 2003
Statut
Membre
Dernière intervention
27 septembre 2004

On peu lire dans mon script: match(/^d+/)+
j'ai oublié le backslash (desolé), il fallait lire: match(/^\d+/)+
De toute facon, ca ne sert qu'à enlever la partie decimal du nombre.

Bon maintenant: essayes mon code (corrigé) et essayes le tien, iwaweb. Tu remarqueras que tant que tu n'affiches pas le nombre d'année ecoulées entre les deux dates (comme toi, juste les semaines et les jours), l'importance des annees bissextiles est completement inutiles. En effet, la soustraction entre deux dates retourne les milisecondes en tenant compte deja des annees bissextiles. Donc tant que tu ne veux pas diviser le nombre de jours par 365 ou 366 pour afficher le nombre d'année, ca ne sert à rien de savoir lequelles le sont ou pas.

Laissez l'object "Date" faire son travail de comparaison. Il vous dira (à madiken et à toi) bien plus rapidement et plus surement si une date est:
* bonne ex: 2003fevrier31 [new Date(2003,1,31) => return 2003mars3;] facile à verifier que le gars c'est fourré, tester les mois.
* plus petite d1<d2
* et son ecart avec une autre date. d1-d2

Pour finir tu titres: "la duree precise"... je pense que ma methode ne limite pas la precision. la tienne si. Je ne dis pas ca pour te decourager. Je trouve ca super les gens qui partagent leur code. Et puis si ca se trouve, c'est moi qui me trompe...

bonne journee
Philippe
iwaweb
Messages postés
56
Date d'inscription
dimanche 22 octobre 2000
Statut
Membre
Dernière intervention
14 décembre 2017

L'interêt de mon code c'est que ça marche pour les années bissextiles.

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.