Цитата Сообщение от Алексей87 Посмотреть сообщение
Ну отличия принципиального конечно нет, согласен, просто описал алгоритм, а по поводы "Сравнивать с нужными датами", это э какая простыня то получится расписанная, 12 месяцев, и черт его знает сколько лет, или я чего то не понимаю?
Все довольна просто будет, если перейти к переменным DATE

1.
Делаем функцию, которая преобразовывает дату ПЛК(год,месяц,день) в DATE
FUNCTION CurDATE:
Код:
FUNCTION CurDATE : DATE
VAR
   CurTimeExInst: CurTimeEx;
    CurSystemTimeDate: SystemTimeDate;
    CurSysTime64: SysTime64;
    year: INT;
    second: INT;
    day: INT;
    hour: INT;
    minute: INT;
    month: INT;
    count: INT;
END_VAR

CurTimeExInst(TimeDate := CurSystemTimeDate, SystemTime := CurSysTime64);
    year :=CurSystemTimeDate.Year;
    month :=CurSystemTimeDate.Month;
    day :=CurSystemTimeDate.Day;
    hour :=CurSystemTimeDate.Hour;
    minute :=CurSystemTimeDate.Minute;
    second :=CurSystemTimeDate.Second;
(*------------------------------------------------------------------------*)
(*Вычислить дату с учетом високосных лет*)
IF month > 2 THEN
    count := (month - 1) * 30;
    IF month > 7 THEN count := count + SHR(month - 3,1);
ELSE count := count + SHR(month - 4,1); END_IF;
    (* проверить на високосный год и добавить один день если год високосный *)
    IF SHL(year,14) = 0 THEN count := count + 1; END_IF;
ELSE
    count := (month - 1) * 31;
END_IF;
CurDATE:=DWORD_TO_DATE((INT_TO_DWORD(count + day - 1)
               + SHR(INT_TO_DWORD(year) * 1461 - 2878169, 2)) * 86400);

2.
Берем из OSCAT, с некоторой модификацией функцию DAY_OF_MONTH
FUNCTION DAY_OF_MONTH:
Код:
FUNCTION DAY_OF_MONTH : INT
VAR_INPUT
	IDATE : DATE;
END_VAR
VAR
	leap: INT;
	MTH_OFS: ARRAY [1..12] OF INT  := 0,31,59,90,120,151,181,212,243,273,304,334;
	LEAP_OF_DATE: BOOL;
END_VAR
LEAP_OF_DATE := SHL(((DATE_TO_DWORD(idate) + 43200) / 31557600), 30) = 16#80000000;
(* calculate the day in the year *)
DAY_OF_MONTH := DAY_OF_YEAR(idate);
(* leap will be set to one for a leap year *)
leap := BOOL_TO_INT(LEAP_OF_DATE);
(* if leap year deduct one from the days of the year *)
DAY_OF_MONTH := DAY_OF_MONTH - leap;
(* search if we are in month december to march ? *)
IF DAY_OF_MONTH > MTH_OFS[9] THEN
	IF DAY_OF_MONTH > MTH_OFS[11] THEN
		IF DAY_OF_MONTH > mth_ofs[12] THEN
			DAY_OF_MONTH := DAY_OF_MONTH - MTH_OFS[12];
		ELSE
			DAY_OF_MONTH := DAY_OF_MONTH - MTH_OFS[11];
		END_IF;
	ELSE
		IF DAY_OF_MONTH > mth_ofs[10] THEN
			DAY_OF_MONTH := DAY_OF_MONTH - MTH_OFS[10];
		ELSE
			DAY_OF_MONTH := DAY_OF_MONTH - MTH_OFS[9];
		END_IF;
	END_IF;
ELSIF DAY_OF_MONTH > MTH_OFS[5] THEN
	IF DAY_OF_MONTH > MTH_OFS[7] THEN
		IF DAY_OF_MONTH > mth_ofs[8] THEN
			DAY_OF_MONTH := DAY_OF_MONTH - MTH_OFS[8];
		ELSE
			DAY_OF_MONTH := DAY_OF_MONTH - MTH_OFS[7];
		END_IF;
	ELSE
		IF DAY_OF_MONTH > mth_ofs[6] THEN
			DAY_OF_MONTH := DAY_OF_MONTH - MTH_OFS[6];
		ELSE
			DAY_OF_MONTH := DAY_OF_MONTH - MTH_OFS[5];
		END_IF;
	END_IF;
ELSIF DAY_OF_MONTH > MTH_OFS[3] THEN
	IF DAY_OF_MONTH > MTH_OFS[4] THEN
		DAY_OF_MONTH := DAY_OF_MONTH - MTH_OFS[4];
	ELSE
		DAY_OF_MONTH := DAY_OF_MONTH - MTH_OFS[3];
	END_IF;
ELSE
	(* since now we must be in february or january we need to add leap again *)
	DAY_OF_MONTH := DAY_OF_MONTH + leap;
	IF DAY_OF_MONTH > MTH_OFS[2] THEN DAY_OF_MONTH := DAY_OF_MONTH - mth_ofs[2]; END_IF;
	(* since nothing was true before, day_of_month must already be good *)
END_IF;

3. Для FUNCTION DAY_OF_MONTH нужна еще одна функция из OSCAT
Скрытый текст:
Код:
FUNCTION DAY_OF_YEAR : INT
VAR_INPUT
	IDATE : DATE;
END_VAR
DAY_OF_YEAR := UDINT_TO_INT((DATE_TO_UDINT(idate) / UDINT#86400) MOD UDINT#1461);
IF DAY_OF_YEAR > 729 THEN
	IF DAY_OF_YEAR > 1095 THEN DAY_OF_YEAR := DAY_OF_YEAR - 1095; ELSE DAY_OF_YEAR := DAY_OF_YEAR - 729; END_IF;
ELSIF DAY_OF_YEAR > 364 THEN
	DAY_OF_YEAR := DAY_OF_YEAR - 364;
ELSE
	DAY_OF_YEAR := DAY_OF_YEAR + 1;
END_IF;


А дальше все просто, как три пальца...
Захват-1.png