//String timestamp '2023-06-16T14:10:00Z' parse to RTC_TYPE //utc_STRING: STRING; In VAR; //utc_RTC: RTC_TYPE; Out VAR; //conv_WARN: BOOL; Out VAR; //sl: INT; Local VAR; //i: INT; Local VAR; //step: INT; Local VAR; //tmp_char: STRING; Local VAR; //probe_char: STRING; Local VAR; sl := LEN(UTC_string); IF sl < 1 THEN //Get input str length, if blank, then skip further exec RETURN; END_IF; probe_char := ''; step := 0; conv_WARN := FALSE;// On each CASE step will check validity of converted value, and ret TRUE if mess up. FOR i := 1 TO sl DO tmp_char := MID(UTC_string, 1, i); IF tmp_char = '0' OR tmp_char = '1' OR tmp_char = '2' OR tmp_char = '3' OR tmp_char = '4' OR tmp_char = '5' OR tmp_char = '6' OR tmp_char = '7' OR tmp_char = '8' OR tmp_char = '9' THEN //Check readed char digit or not probe_char := CONCAT(probe_char, tmp_char); ELSE IF probe_char = '' THEN CONTINUE; //Keep reading if does not met any digit before, END_IF; //jump to the next char CASE step OF //Fill RTC struct one by one, reading input string left to right 0: utc_RTC.YEAR := TO_UINT(probe_char); conv_WARN := conv_WARN OR (utc_RTC.YEAR < 1970) OR (utc_RTC.MONTH > 2100); 1: utc_RTC.MONTH := TO_USINT(probe_char); conv_WARN := conv_WARN OR (utc_RTC.MONTH < 1) OR (utc_RTC.MONTH > 12); 2: utc_RTC.DAY := TO_USINT(probe_char); conv_WARN := conv_WARN OR (utc_RTC.DAY < 1) OR (utc_RTC.DAY > 31); 3: utc_RTC.HOURS := TO_USINT(probe_char); conv_WARN := conv_WARN OR (utc_RTC.HOURS > 23); 4: utc_RTC.MINUTES := TO_USINT(probe_char); conv_WARN := conv_WARN OR (utc_RTC.MINUTES > 59); 5: utc_RTC.SECONDS := TO_USINT(probe_char); conv_WARN := conv_WARN OR (utc_RTC.SECONDS > 59); END_CASE; step := step + 1; probe_char := ''; END_IF; END_FOR;