### 2. FC_GetWeekNumber (ISO 8601 compliant) ```iecst FUNCTION "FC_GetWeekNumber" : UINT TITLE = 'Get ISO 8601 Week Number' VERSION : 1.0 VAR_INPUT stDateTime : DT; // Date & time to evaluate END_VAR VAR_TEMP iYear : INT; iMonth : INT; iDay : INT; iJan1_DayOfWeek : INT; // 0=Sunday ... 6=Saturday iDayOfYear : INT; iDoW : INT; // Day of week of input date iWeek : INT; END_VAR BEGIN // Extract components iYear := DT_TO_DATE(stDateTime).YEAR; iMonth := DT_TO_DATE(stDateTime).MONTH; iDay := DT_TO_DATE(stDateTime).DAY; // Day of week (Siemens: 1=Monday ... 7=Sunday) iDoW := WEEKDAY(DT_TO_DATE(stDateTime)); // 1..7 // Approximate day of year iDayOfYear := DAY_OF_YEAR(DT_TO_DATE(stDateTime)); // Find weekday of Jan 1st of the year iJan1_DayOfWeek := WEEKDAY(DATE(iYear,1,1)); // ISO 8601: week 1 = week with first Thursday // Algorithm approximation (good enough for most cases) iWeek := (iDayOfYear + (iJan1_DayOfWeek - 1) + 3) / 7; // basic // Correction for years where Jan 1..3 belong to previous year IF (iJan1_DayOfWeek >= 5) AND (iDayOfYear <= 3) THEN iWeek := 53; // or 52 depending on year - simplified // Better: call previous year calculation if needed ELSIF (iJan1_DayOfWeek <= 4) AND (iDayOfYear >= 363) THEN // Check if week 53 IF (iDoW + (7 - iJan1_DayOfWeek)) > 364 THEN iWeek := 53; END_IF; END_IF; "FC_GetWeekNumber" := INT_TO_UINT(iWeek); END_FUNCTION