Creazione di una funzione in SCL che riceve in ingresso una variabile di tipo “Date_and_Time” (ovvero una variabile che rappresenta una data e un ora, ad esempio DT#2016-03-1-12:30:00.000) e restituisce il numero del giorno dell’anno.
Da notare che tale funzione tiene ovviamente conto degli anni bisestili, infatti se la data in ingresso fosse DT#2016-03-1-12:30:00.000 l’uscita sarà num_giorno=61, mentre se la data in ingresso fosse DT#2015-03-1-12:30:00.000 (ovvero la stessa, ma di un anno non bisestile) allora l’uscita sarà num_giorno=60.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 | FUNCTION "numero_giorno_anno" : Void { S7_Optimized_Access := 'FALSE' } VERSION : 0.1 VAR_INPUT data_in : Date_And_Time; END_VAR VAR_OUTPUT num_giorno : Int; END_VAR VAR_TEMP data_in_tmp : Date_And_Time; data_in_array AT data_in_tmp : Array[0..7] of Byte; count : Int; anno_bisestile : Bool; anno : Int; num_giorno_tmp : Int; mese : Int; num_giorno_mese_corrente : Int; END_VAR BEGIN //calcola il numero del giorno dell'anno #data_in_tmp := #data_in; #count := 0; #anno := BCD16_TO_INT(#data_in_array[0]); #anno_bisestile := 0; #num_giorno_tmp := 0; WHILE #count < 97 DO IF #anno = #count THEN #anno_bisestile := 1; EXIT; END_IF; IF #count <> 96 THEN #count := #count + 4; ELSIF #count=96 THEN #count := 97; EXIT; END_IF; END_WHILE; #mese := BCD16_TO_INT(#data_in_array[1]); CASE #mese OF 1: #num_giorno_tmp := 0; 2: #num_giorno_tmp := 31; //gen 3: #num_giorno_tmp := 59; //feb 4: #num_giorno_tmp := 90; //mar 5: #num_giorno_tmp := 120; //apr 6: #num_giorno_tmp := 151; //mag 7: #num_giorno_tmp := 181; //giu 8: #num_giorno_tmp := 212; //lug 9: #num_giorno_tmp := 243; //ago 10: #num_giorno_tmp := 273; //set 11: #num_giorno_tmp := 304; //ott 12: #num_giorno_tmp := 334; //nov END_CASE; // se siamo in un anno bisestile allora bisogna aggiungere // un giorno se la data è a partire dal primo marzo IF #anno_bisestile AND #mese > 2 THEN #num_giorno_tmp := #num_giorno_tmp + 1; END_IF; #num_giorno_mese_corrente := BCD16_TO_INT(#data_in_array[2]); #num_giorno := #num_giorno_tmp+ #num_giorno_mese_corrente; END_FUNCTION |
Come si può vedere il calcolo del numero del giorno avviene in due fasi separate, ovvero se come data in ingresso abbiamo DT#2016-03-1-12:30:00.000, la funzione sopra calcola prima il numero del giorno (dell’anno) relativo all’ultimo giorno del mese precedente a quello della data in ingresso (quindi in questo caso il numero del giorno dell’anno al 2016-02-29) e salva tale valore nella variabile intera “#num_giorno_tmp” (ossia nell’esempio fatto num_giorno_tmp=60, che la funzione sopra calcola come 59+1, essendo un anno bisestile) e dopo inizializza la variabile intera “#num_giorno_mese_corrente” al numero del giorno del mese della data in ingresso (in questo caso “#num_giorno_mese_corrente=1”).
A questo punto il numero del giorno dell’anno è dato semplicemente dalla somma delle ultime due variabili calcolate.
Funzione scaricabile dal seguente Download