Все довольна просто будет, если перейти к переменным 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





Ответить с цитированием