Soustraction format DATE

Forum traitant des automates industriels de marque Schneider - Telemecanique
Avatar du membre
Ulairi
Expert de l'héxadécimal
Expert de l'héxadécimal
Messages : 366
Enregistré le : 20 oct. 2015, 06:22

Re: Soustraction format DATE

Message par Ulairi »

Sinon, le format DATE, c'est du BCD, tu peux aussi récupérer les années / mois / jours indépendamment dans différents INT pour faire tes soustractions ensuite.
Enseignant en BTS électrotechnique (Pas taper sur l'intru !)
Avatar du membre
geronimo
Forcené des structures
Forcené des structures
Messages : 169
Enregistré le : 20 oct. 2015, 08:46

Re: Soustraction format DATE

Message par geronimo »

merci beaucoup
Je suis sur une idée, je la poste dès que sa marche
Avatar du membre
Cyril93
Maître du binaire
Maître du binaire
Messages : 484
Enregistré le : 29 oct. 2015, 14:22
Localisation : IDF

Re: Soustraction format DATE

Message par Cyril93 »

geronimo a écrit :merci beaucoup
Je suis sur une idée, je la poste dès que sa marche
Avec l'autorisation de geronimo :D je poste la réponse. pour la soustraction du format DATE avec le logiciel UNITY PRO

Une des solutions consiste à convertir la DATE en nombre de jours depuis le 01/01/1990 (voir format Date sur l'aide Unity) par exemple le 01/01/1990 sera le jour 0, le 02/01/1990 sera le jour 1, le 03/01/1990 le jour 3...................... je sais ça va vous avez compris :D :D

pour cela créer un DFB nommé DATE_TO_DINT puis déclaré les variables suivantes :

- en entrées : IN_DATE type DATE
- en sorties : RESULT type DINT ( ça sera notre numéro de jour depuis le 01/01/1990)
- en privé : DateArray type ARRAY[0..1] OF INT, year type INT, month type INT, day type INT et i type INT

puis dans une section en ST copier coller ce code ;)

Code : Tout sélectionner

(*
==========================================================================================
Fonction identique à DATE_TO_DINT sur siemens Step7 (SCL)
Renvoi le numéro du jour depuis le 01/01/1990 en commençant par 0
==========================================================================================						
Cyril93 
==========================================================================================
*)



(* Séparation de la date en 3 INT *)
DateArray := DATE_TO_ARINT (IN := IN_DATE); 
year:= BCD_TO_INT(DateArray[1]);
month:=BCD_TO_INT(SHR(DateArray[0],8));
day:=BCD_TO_INT(DateArray[0] AND 16#00FF);

(* Initialise le résultat à chaque tour de cycle *)
RESULT:=0;

(* Ajoute les jours par année depuis 1990 jusqu'à l'année n-1 *)
For i:=1990 To year-1 DO
	IF SHL(i,14)=0 THEN	(* Année bissextile *)
		RESULT:=RESULT+366;
	ELSE
		RESULT:=RESULT+365;
	END_IF;
END_FOR;

(* Ajoute les jours par mois jusqu'au mois n-1 *)
For i:=1 To month-1 DO
	CASE i OF
	
	1,3,5,7,8,10,12 : RESULT:=RESULT+31;

	4,6,9,11: RESULT:=RESULT+30;

	2: IF SHL(year,14)=0 THEN
		RESULT:=RESULT+29;
	   ELSE
		RESULT:=RESULT+28;
	   END_IF;

	END_CASE;
		
END_FOR;

(* Ajoute le nombre de jour du mois courant *)
RESULT:=RESULT+INT_TO_DINT(day);
RESULT:=RESULT-1;	(* Résultat -1 pour être identique à DATE_TO_DINT Siemens Step7 *)
ensuite il suffit de faire deux instances du DFB (une pour chaque date) et de soustraire les deux numéros pour avoir l'écart en nombre de jour, et on peux dépasser la limite des 49 jours de SUB_DATE_DATE :evil:


maintenant si on veux ajouter par exemple 86 jours à la date d'aujourd'hui et afficher cette nouvelle Date en format DATE, il nous faut la fonction inverse qui serait DINT_TO_DATE :mrgreen:

créons donc un nouveau DFB, DINT_TO_DATE avec les variables suivantes :o

- en entrées : IN_DAY type DINT
- en sorties : RESULT_DATE type DATE
- en privé : dateArray type ARRAY[0..1] OF INT, year type INT, month type INT, day type INT, temp type DINT et monthArray type ARRAY[1..12] OF INT pour ce tableau monthArray mettre dans la colonne Valeur le nombre de jour de chaque mois (mettre 28 pour février de toute façon pour ce mois cela n'a pas d'importance)

copier coller dans une section ST le code suivant :

Code : Tout sélectionner

(*
==========================================================================================
Fonction inverse à DATE_TO_DINT 
Renvoi la DATE depuis le numéro du jour
==========================================================================================						
Cyril93 
==========================================================================================
*)


(* Initialise les variables *)
temp:=IN_DAY;
year:=1990;
month:=01;
day:=01;

(* calcul de l'année *)
WHILE temp >= 365 DO
	IF SHL(year,14)=0 THEN	(* Année bissextile *)
		temp:=temp-366;
	ELSE
		temp:=temp-365;
	END_IF;
	IF temp< 0 THEN	
		EXIT;
	END_IF;
	year:=year+1;

END_WHILE;

(* calcul du mois *)
IF SHL(year,14)=0 THEN
	monthArray[2]:=29;
ELSE
	monthArray[2]:=28;
END_IF;

REPEAT
	IF temp >= INT_TO_DINT(monthArray[month]) THEN
		CASE month OF
	
		1,3,5,7,8,10,12 : temp:=temp-31; 						

		4,6,9,11: temp:=temp-30; 

		2: IF SHL(year,14)=0 THEN
			temp:=temp-29; 
	  	   ELSE
			temp:=temp-28; 
	  	   END_IF;

		END_CASE;

		month:=month+1;
	END_IF;
	
UNTIL temp < INT_TO_DINT(monthArray[month])
END_REPEAT;

(* Reste le jour *)
IF temp = -1 THEN 
	day:=monthArray[12];
	month:=12;
ELSE
	day:=DINT_TO_INT(temp+1);	
END_IF;

(* converti au format DATE *)
DateArray[1]:=INT_TO_BCD(IN:=year);
DateArray[0]:=SHL(INT_TO_BCD(month),8) OR INT_TO_BCD(day AND 16#00FF); 
RESULT_DATE:=ARINT_TO_DATE(IN:=DateArray);

voilà maintenant on peux faire ce genre de calcul : (testé sur le simulateur d'Unity Pro car j'ai pas de CPU sous la main ;) )

Merde, ça tombe un samedi !!
exemple_conv.PNG
Répondre