. Siemens SCL

: 2013-02-18

: komatic

: SCL


:
- DIN 1355 / ISO 8601
-



: Siemens
SCL
2012





:

CWD_EU:

CW 1 , 4
CW 7


CWD_US:

CW 1 1
CW 7



calendar

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



calendar

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





: 6585

.

:

(4000 max):

: