Tool for determining the calendar day
Bij onze vrienden van Siemens kun je deze downloaden. Maar wel pas nadat je betaald hebt 🙄 (CWD_EU) Dus heb ik ‘m zelf maar geschreven in SCL.
FUNCTION FC370_DAYOFYEAR : INT TITLE= 'FC370_DAYOFYEAR' NAME : DAYOFYR FAMILY : PROCESS AUTHOR : VMI_JFO VERSION : '1.0' //Jfo - 29 juni 2011: This function calculates the number of the day of the year. // This will generate 1-365 for normal years, and 1-366 for leap years. // NOTE: this will work until year 2100! Year 2100, 2200, 2300... are NOT leap years! VAR_INPUT END_VAR VAR_TEMP Err_ReadDate : INT; // error code return tmpDATE : DT; // time structure current_DT AT tmpDATE: ARRAY[1..8] OF BYTE; // array for access to time structures zdn : INT; // help variable year : INT; // year, format: ?? (19XX - 20XX) num_of_month : INT; // number of month, jan -1, feb -2,... day_of_month : INT; // no comments :) day_of_week : INT; // !!! sun -1, mon -2, tus -3,..., . days : ARRAY[1..12] OF INT; // array with number of days of all months i : INT; numberofdays : INT; result_INT : INT; result_REAL : REAL; END_VAR BEGIN Err_ReadDate := READ_CLK( CDT := tmpDATE); // Getting of current date year := WORD_TO_INT(SHR(IN:=current_DT[1],N:=4))*10 + WORD_TO_INT(current_DT[1] AND 16#0F); // calculation of year num_of_month := WORD_TO_INT(SHR(IN:=current_DT[2],N:=4))*10 + WORD_TO_INT(current_DT[2] AND 16#0F); // calculation numb of month day_of_month := WORD_TO_INT(SHR(IN:=current_DT[3],N:=4))*10 + WORD_TO_INT(current_DT[3] AND 16#0F); // calculation of day day_of_week := WORD_TO_INT(current_DT[8] AND 16#0F); // calculation day of week //--------------------------------------------------------------------------- // Fill in the number of days of the months //--------------------------------------------------------------------------- days[1] := 31; //jan days[2] := 28; //feb (note: leap year day will be added further...) days[3] := 31; //mrt days[4] := 30; //apr days[5] := 31; //may days[6] := 30; //jun days[7] := 31; //jul days[8] := 31; //aug days[9] := 30; //sep days[10] := 31; //oct days[11] := 30; //nov days[12] := 31; //dec //--------------------------------------------------------------------------- // Leap year? If it is a leap year then we have to add 1 extra day for month february. //--------------------------------------------------------------------------- result_INT := year / 4; result_REAL := INT_TO_REAL(year) / 4; IF result_REAL - INT_TO_REAL(result_INT) = 0 THEN days[2] := days[2] + 1; //feb END_IF; //--------------------------------------------------------------------------- // Calculate number days of previous months. //--------------------------------------------------------------------------- numberofdays := 0; FOR i:= 1 TO num_of_month - 1 BY 1 DO numberofdays := numberofdays + days[i]; END_FOR; //--------------------------------------------------------------------------- // Calculate number days of current months. //--------------------------------------------------------------------------- numberofdays := numberofdays + day_of_month; //--------------------------------------------------------------------------- // Move result to the output. //--------------------------------------------------------------------------- FC370_DAYOFYEAR := numberofdays; END_FUNCTION
From Siemens:
FUNCTION CWD_EU : INT (* F U N C T I O N C L N D R _ W E E K _ D A Y ( E U ) ================================================================= This function calculates the calendar week for... - the date specified in input parameter "Date_in" (format: DATE) if "CPU_clock" = FALSE. - the current CPU date if "CPU_clock" = TRUE. (Though "Date_in" is not used in this case, is has to be fed. with any value) The calendar week is written to the output parameter "week" (format: INT). The calendar day is written to the output parameter "day" (format: INT). The week number is calculated subject to DIN 1355 / ISO 8601. Week no. 1 is the first week, which includes at least four days of the new year. The beginning of a week is always Monday. The function can be used from year 1991 to 2089. Faults: Faults are monitored by means of the return value "CWD_EU" respektively "RET_VAL". - No error: 0000H - If input "CPU_clock" = FALSE: 8001H: "Date_in" out of 1991-01-01...2089-12-31 - If input "CPU_clock" = TRUE: Error messages of READ_CLK SFC1 revision history: 01.01.2009 Version 1.1: New querry for checking calendar week: When variable 'tValue' is 53 than it has to be checked, if 'int_Date' is in week 53 of this year or in the first week of the following year. *) TITLE= 'Calendar Week/Day (EU)' AUTHOR: Hall FAMILY: TIME_FCT NAME: CWD_EU VERSION: '1.1' VAR_INPUT CPU_clock : BOOL; Date_in : DATE; END_VAR VAR_OUTPUT week : INT; day : INT; END_VAR VAR_TEMP CPU_DT : DATE_AND_TIME; TOD_0 : TIME_OF_DAY; DT_ref : DATE_AND_TIME; DT_ref_bytes AT DT_ref : ARRAY[0..7] OF BYTE; //DT_ref_bytes[0] Year, //DT_ref_bytes[1] Month, //DT_ref_bytes[2] Day, //DT_ref_bytes[3] Hour, //DT_ref_bytes[4] Minute, //DT_ref_bytes[5] Second, //DT_ref_bytes[6] Msec, //DT_ref_bytes[7] Weekday 1 ... 7 (1 = Sunday) int_Date : DATE; Date_1Jan : DATE; weekday_1Jan : INT; weekday_31Dec : INT; weekday_1Jan_prevY : INT; weekday_31Dec_prevY : INT; day_corr : INT; tValue : INT; END_VAR BEGIN //For date, use input parameter "Date_in" or CPU clock. IF CPU_clock THEN CWD_EU := READ_CLK(CDT := CPU_DT); //SFC 1 //Leave program, if error in return value of READ_CLK, otherwise use CPU date and go on. IF CWD_EU <> 0 THEN RETURN; ELSE int_Date := DT_DATE(CPU_DT); //FC 6 IEC functions END_IF; ELSE //Leave program, if "Date_in" is out of limits, otherwise use "Date_in" and go on. //365 = 1991-01-01; 36524 = 2089-12-31 IF DATE_TO_DINT(Date_in) < 365 OR DATE_TO_DINT(Date_in) > 36524 THEN CWD_EU := INT#16#8001; RETURN; ELSE CWD_EU := 0; int_DATE := Date_in; END_IF; END_IF; //Date of January 1st in the current year in format DATE TOD_0 := TOD#00:00:00; DT_ref := D_TOD_DT(IN1:=int_Date, IN2:=TOD_0); //FC 3 IEC functions DT_ref_bytes[1] := 1; DT_ref_bytes[2] := 1; Date_1Jan := DT_DATE(DT_ref); //FC 6 IEC functions //Number of days in the current year up to "int_Date" day := DINT_TO_INT(DATE_TO_DINT(int_Date) - DATE_TO_DINT(Date_1Jan)) + 1; //Day of week of January, 1st in the current year weekday_1Jan := DT_DAY(DT_ref); //FC 7 IEC functions //Correction of numer of days regarding the weekday on January 1st CASE weekday_1Jan OF 1: day_corr := day -2; //Sunday 2: day_corr := day -1; //Monday 3: day_corr := day ; //Tuesday 4: day_corr := day +1; //Wednesday 5: day_corr := day +2; //Thursday 6: day_corr := day -4; //Friday 7: day_corr := day -3; //Saturday END_CASE; //With negative "day_corr", take last week number of last year. IF day_corr < 0 THEN //Predecessor of year '00' is '99'; otherwise it's current year minus 1 IF DT_ref_bytes[0] = B#16#00 THEN DT_ref_bytes[0] := B#16#99; ELSE DT_ref_bytes[0] := WORD_TO_BYTE(INT_TO_BCD(BCD_TO_INT(DT_ref_bytes[0]) - 1)); END_IF; //Weekdays of Jan 1st and Dec 31th of precious year weekday_1Jan_prevY := DT_DAY(DT_ref); //FC 7 IEC functions DT_ref_bytes[1] := B#16#12; DT_ref_bytes[2] := B#16#31; weekday_31Dec_prevY := DT_DAY(DT_ref); //FC 7 IEC functions //Only if one of the days Jan 1st or Dec 31th of the previous year //is a Thursday, the current day is in week 53 of the previous year, //otherwise in week 52. IF weekday_1Jan_prevY = 5 OR weekday_31Dec_prevY = 5 THEN week := 53; ELSE week := 52; END_IF; ELSE //With positive "day_corr", take "day_corr" for calculating the calendar week. tValue := day_corr/7 + 1; IF (tValue = 53) THEN //Only if one of the days Jan 1st or Dec 31th is a Thursday, //the day is in week 53 of the current year, otherwise in week 1 of the following year. DT_ref_bytes[1] := B#16#12; DT_ref_bytes[2] := B#16#31; weekday_31Dec := DT_DAY(DT_ref); IF(weekday_1Jan = 5 OR weekday_31Dec = 5) THEN week := 53; ELSE week := 1; END_IF; ELSE week := tValue; END_IF; END_IF; END_FUNCTION
and
FUNCTION CWD_US : INT (* F U N C T I O N C L N D R _ W E E K _ D A Y ( U S ) ================================================================= This function calculates the calender week and calender day for... - the date specified in input parameter "Date_in" (format: DATE) if "CPU_clock" = FALSE. - the current CPU date if "CPU_clock" = TRUE. (Though "Date_in" is not used in this case, is has to be fed. with any value) The calendar week is written to the output parameter "week" (format: INT). The calendar day is written to the output parameter "day" (format: INT). The week number is calculated subject to US use and MS Excel. It is always week no. 1 which includes January 1st. First and last calender week of the year need not to have seven days. The beginning of a week is always Sunday. The function can be used from year 1990 to 2089. Faults: Faults are monitored by means of the return value "CWD_US" respektively "RET_VAL". - No error: 0000H - If input "CPU_clock" = FALSE: 8001H: "Date_in" out of 1990-01-01...2089-12-31 - If input "CPU_clock" = TRUE: Error messages of READ_CLK SFC1 *) TITLE= 'Calendar Week/Day (US)' AUTHOR: Hall FAMILY: TIME_FCT NAME: CWD_US VERSION: '1.0' VAR_INPUT CPU_clock : BOOL; Date_in : DATE; END_VAR VAR_OUTPUT week : INT; day : INT; END_VAR VAR_TEMP CPU_DT : DATE_AND_TIME; TOD_0 : TIME_OF_DAY; DT_ref : DATE_AND_TIME; DT_ref_bytes AT DT_ref : ARRAY[0..7] OF BYTE; //DT_ref_bytes[0] Year, //DT_ref_bytes[1] Month, //DT_ref_bytes[2] Day, //DT_ref_bytes[3] Hour, //DT_ref_bytes[4] Minute, //DT_ref_bytes[5] Second, //DT_ref_bytes[6] Msec, //DT_ref_bytes[7] Weekday 1 ... 7 (1 = Sunday) int_Date : DATE; Date_1Jan : DATE; weekday_1Jan : INT; day_corr : INT; END_VAR BEGIN //For date, use input parameter "Date_in" or CPU clock. IF CPU_clock THEN CWD_US := READ_CLK(CDT := CPU_DT); //SFC 1 //Leave program, if error in return value of READ_CLK, otherwise use CPU date and go on. IF CWD_US <> 0 THEN RETURN; ELSE int_Date := DT_DATE(CPU_DT); //FC 6 IEC functions END_IF; ELSE //Leave program, if "Date_in" is out of limits, otherwise use "Date_in" and go on. //0 = 1990-01-01; 36524 = 2089-12-31 IF DATE_TO_DINT(Date_in) < 0 OR DATE_TO_DINT(Date_in) > 36524 THEN CWD_US := INT#16#8001; RETURN; ELSE CWD_US := 0; int_DATE := Date_in; END_IF; END_IF; //Date of January 1st in the current year in format DATE TOD_0 := TOD#00:00:00; DT_ref := D_TOD_DT(IN1:=int_Date, IN2:=TOD_0); //FC 3 IEC functions DT_ref_bytes[1] := 1; DT_ref_bytes[2] := 1; Date_1Jan := DT_DATE(DT_ref); //FC 6 IEC functions //Number of days in the current year up to "int_Date" day := DINT_TO_INT(DATE_TO_DINT(int_Date) - DATE_TO_DINT(Date_1Jan)) + 1; //Day of week of January, 1st in the current year weekday_1Jan := DT_DAY(DT_ref); //FC 7 IEC functions //Correction of numer of days regarding the weekday on January 1st CASE weekday_1Jan OF 1: day_corr := day -1; //Sunday 2: day_corr := day ; //Monday 3: day_corr := day +1; //Tuesday 4: day_corr := day +2; //Wednesday 5: day_corr := day +3; //Thursday 6: day_corr := day +4; //Friday 7: day_corr := day +5; //Saturday END_CASE; //Calculate calendar week. week := day_corr/7 + 1; END_FUNCTION