Date difference

Voici une libre contribution au calcul de différence de dates :
<code 4D>
// DAT_Date_Difference_o bernard //
If (True)
// 0C741F7C81764A5393F43AC4C88B72D6

  //<STX>$Date_difference_t:=DAT_Date_Difference (MyObject) </STX>
  //________________________________________________________________________________
  //DESCRIPTION FONCTIONNELLE<DSC>
  //<FR>
  //Cette fonction calcule la différence de 2 dates et retourne :
  //- la différence de dates sous une forme textuelle dans $0 et dans l'objet
  //- une série de formats spécifiques dans l'objet
  //. nombre d'années en décimal, sans nombre de mois ni de jours
  //. nombre de mois partiel (à utiliser avec le nombre d'années sans le nombre de jours) ou total, en décimal 
  //. nombre de jours partiel (à utiliser avec le nombre d'années sans le nombre de mois) ou total, en décimal. 

  //Si la deuxième date n'est pas indiquée, on prend la date du jour.

  //DAT_Date_Difference_o est une version de DAT_Date_Difference adaptée à l'utilisation d'un paramètre objet.
  //</FR>

  //<EN>
  //This function computes the difference between 2 dates and returns :
  //- the difference of dates as a string in $0 and in the object
  //- a series of specific formats in the object
  //. number of years in decimal, without number of months and days
  //. partial (to be used with number of years without number of days) or total number of months, decimal
  //. partial (to be used with number of years without number of months) or total number of days, decimal. 

  //If the second date is not passed, current date is used

  //DAT_Date_Difference_o is a version of DAT_Date_Difference adapted to use parameter object.
  //</EN>


  //</DSC>
  //________________________________________________________________________________
  //AMELIORATIONS A APPORTER <AML>
  //</AML>
  //________________________________________________________________________________
  //CREATION par Bernard Escaich <DAT>
  //•1• 08/02/2004 00:00:00  
  //•2• 21/11/2006 00:00:00  
  //•3• 27/02/2007 23:34:57  
  //•4• 23/03/2009 09:11:44  <TAG>
  //•5• 04/04/2014 11:57:10  Réécriture
  //•6• 10/05/2014 23:19:23  Partie décimale exprimée en nombre de jours du mois ou de l'année de fin, au lieu des
  //////                         valeurs moyennes 30 ou 365,25
  //•7• 30/12/2018 14:51:28  
  //•8• 30/12/2018 16:08:39  Modification pour le paramètre objet
  //</DAT>
  //________________________________________________________________________________
  //COMPOSANT <CMP>
  //</CMP>
  //________________________________________________________________________________
  //PARAMETRES <PRM>
C_OBJECT($1)
  // Date_begin : Date de début
  // Date_end : Date de fin (Optionnel ; date du jour par défaut)
  // Nb_Years : Nombre d'années ; si Nil, on convertit le nombre d'années en mois (x 12)
  // Nb_Months : Nombre de mois ; si Nil, on retourne uniquement le nombre de jours (ni les années, ni les mois)
  // Nb_Days : Nombre de jours
  // Language : langue (anglais, français fournis)
C_TEXT($0)  //Durée en chiffres et lettres comprenant le nombre d'Années, Mois, Jours
  //</PRM>
  //________________________________________________________________________________
  //TYPAGE DES VARIABLES LOCALES <TVL>
C_BOOLEAN($OK_b)
C_LONGINT($Nb_Params_l)
C_DATE($Date_begin_d)
C_DATE($Date_end_d)
C_LONGINT($Nb_Years_l)
C_LONGINT($Nb_Months_l)
C_LONGINT($Nb_Days_l)
C_LONGINT($NbDays_of_LastMonth_l)
C_LONGINT($NbDays_of_LastYear_l)
C_OBJECT($Parameters_o)
C_TEXT($Date_difference_t)
  //</TVL>
  //TYPAGE DES VARIABLES à reclasser dans les COMPILER_XXX <TVG> 
  //</TVG>
  //TYPAGE DES VARIABLES INTERPROCESS à reclasser <TVI>
  //</TVI>
  //________________________________________________________________________________
  //CONTROLE DES PARAMETRES <CPR>
$Nb_Parameters_l:=Count parameters
If ($Nb_Parameters_l>=1)
	  //Contrôle des paramètres dans le cas d'utilisation normale de la méthode
	If ($Nb_Parameters_l>=1)
		If (Not(Undefined($1)))
			$Parameters_o:=$1
			  //Contrôle de la structure de l'objet
			  //...
			
			$Date_begin_d:=Date($Parameters_o.Date_begin;)
			If (Undefined($Parameters_o.Date_end))
				$Date_end_d:=Current date
			Else 
				$Date_end_d:=$Parameters_o.Date_end
			End if 
			
			If (Undefined($Parameters_o.Language))
				$Parameters_o.Language:="EN"
			End if 
			Case of 
				: ($Parameters_o.Language="EN")
					$Parameters_o.Year:="Year"
					$Parameters_o.Month:="Month"
					$Parameters_o.Day:="Day"
					$Parameters_o.Years:="Years"
					$Parameters_o.Months:="Months"
					$Parameters_o.Days:="Days"
					
				: ($Parameters_o.Language="FR")
					$Parameters_o.Year:="An"
					$Parameters_o.Month:="Mois"
					$Parameters_o.Day:="Jour"
					$Parameters_o.Years:="Ans"
					$Parameters_o.Months:="Mois"
					$Parameters_o.Days:="Jours"
					
					  //Add other languages here
			End case 
			
		End if 
	End if 
	$OK_b:=True
End if 
  //</CPR>
  //________________________________________________________________________________
  //INITIALISATION DES VARIABLES LOCALES <IVL>
  //</IVL>
  //________________________________________________________________________________
  //INITIALISATION DES VARIABLES GLOBALES <IVG>
  //</IVG>

End if
//________________________________________________________________________________
//EXÉCUTION
If ($OK_b)

  //Calcul de la différence en Années, Mois, Jours
$Nb_Years_l:=Year of($Date_end_d)-Year of($Date_begin_d)
If (Add to date($Date_begin_d;$Nb_Years_l;0;0)>$Date_end_d)
	$Nb_Years_l:=$Nb_Years_l-1
End if 

$Nb_Months_l:=Month of($Date_end_d)-Month of(Add to date($Date_begin_d;$Nb_Years_l;0;0))
If ($Nb_Months_l<0)
	$Nb_Months_l:=$Nb_Months_l+12
End if 
If ($Nb_Months_l=0) & ($Date_end_d-Add to date($Date_begin_d;$Nb_Years_l;$Nb_Months_l;0)>335)
	$Nb_Months_l:=12
End if 
If (Add to date($Date_begin_d;$Nb_Years_l;$Nb_Months_l;0)>$Date_end_d)
	$Nb_Months_l:=$Nb_Months_l-1
End if 

$Nb_Days_l:=$Date_end_d-Add to date($Date_begin_d;$Nb_Years_l;$Nb_Months_l;1)-1


  //Chaîne complète de la différence de dates
$Date_difference_t:=$Date_difference_t+((String($Nb_Years_l)+" "+($Parameters_o.Year*Num($Nb_Years_l=1))+($Parameters_o.Years*Num($Nb_Years_l>1)))*Num($Nb_Years_l>0))
$Date_difference_t:=$Date_difference_t+(((", "*Num($Date_difference_t#""))+String($Nb_Months_l)+" "+($Parameters_o.Month*Num($Nb_Months_l=1))+($Parameters_o.Months*Num($Nb_Months_l>1)))*Num($Nb_Months_l>0))
$Date_difference_t:=$Date_difference_t+(((", "*Num($Date_difference_t#""))+String($Nb_Days_l)+" "+($Parameters_o.Day*Num($Nb_Days_l=1))+($Parameters_o.Days*Num($Nb_Days_l>1)))*Num($Nb_Days_l>0))


  //Données complémentaires
$NbDays_of_LastMonth_l:=Add to date(!00-00-00!;Year of($Date_end_d);Month of($Date_end_d)+1;1)-Add to date(!00-00-00!;Year of($Date_end_d);Month of($Date_end_d);1)
$NbDays_of_LastYear_l:=Add to date(!00-00-00!;Year of($Date_end_d);12;31)+1-Add to date(!00-00-00!;Year of($Date_end_d);1;1)

$Nb_Days_total_l:=$Date_end_d-$Date_begin_d

$Nb_Months_decimal_r:=$Nb_Months_l+($Nb_Days_l/$NbDays_of_LastMonth_l)  // A remplacer par nb jours dernier mois

$Nb_Years_decimal_r:=$Nb_Years_l+(($Nb_Days_total_l-(Add to date($Date_begin_d;$Nb_Years_l;0;0)-$Date_begin_d))/$NbDays_of_LastYear_l)

$Nb_Months_total_l:=$Nb_Months_l+($Nb_Years_l*12)

$Nb_Months_decimal_total_r:=$Nb_Months_l+($Nb_Years_l*12)+($Nb_Days_l/$NbDays_of_LastMonth_l)

$Nb_Months_decimal_r:=$Nb_Months_l+($Nb_Days_l/$NbDays_of_LastMonth_l)


  //Alimentation des paramètres de retour
$Parameters_o.Date_difference:=$Date_difference_t
$Parameters_o.Nb_Years:=$Nb_Years_l
$Parameters_o.Nb_Months:=$Nb_Months_l
$Parameters_o.Nb_Days:=$Nb_Days_l
$Parameters_o.Nb_Days_total:=$Nb_Days_total_l
$Parameters_o.Nb_Months_decimal:=$Nb_Months_decimal_r
$Parameters_o.Nb_Years_decimal:=$Nb_Years_decimal_r
$Parameters_o.Nb_Months_total:=$Nb_Months_total_l
$Parameters_o.Nb_Months_decimal_total:=$Nb_Months_decimal_total_r
$Parameters_o.Nb_Months_decimal_r:=$Nb_Months_decimal_r

$0:=$Date_difference_t

End if

//
//________________________________________________________________________________
//AUTOTEST
If ($Nb_Parameters_l=0)

  //On peut enchaîner plusiers tests

End if
//

</code 4D>

Cela fonctionne en général mais j’ai un problème avec les dates ayant une année inférieure à 100 ; malgré plusieurs essais, elles sont converties avec le siècle par défaut.
Est-ce dû au passage pas l’objet ? L’objet a bien la date sur 4 caractères.
Comment traiter ce problème ?

Pour faire plaisir à Bertrand
http://forums.4d.com/4DBB_Main/x_User/4018/files/27911949.zip

Nota : ce serait sympa de charger directement le format c4d !

Bonne année à tous :pray:

: Bernard ESCAICH

Bonne année à tous :pray:
Dinde au whisky, ce soir ? :smiley:

Bizarre l’interpréteur de code ; pourquoi le commentaire “nombre de mois partiel” apparaît-il en gras italique ?
Et bien d’autres anomalies…
Il fait la dinde ?
Trop de whisky ?

: Bernard ESCAICH

j’ai un problème avec les dates ayant une année inférieure à 100 ;
malgré plusieurs essais, elles sont converties avec le siècle par
défaut

SET DEFAULT CENTURY(0;0) ne fonctionne pas ; SET DEFAULT CENTURY(1;0) fixe les dates à partir de 100.

La date !00/00/00! est maudite :

  • !1/1/1!-1 donne !00/00/00!
  • mais Add to date(!00/00/00!;0;0;1*) donne !00/00/00!.
    C’est un bug.
  • ou n’importe quel nombre

Ajouter a date(!00/00/00!;x;y;z) donne 00/00/00 si x, y ou z vaut 0.