Показано с 1 по 9 из 9

Тема: Обнуление переменной

Комбинированный просмотр

Предыдущее сообщение Предыдущее сообщение   Следующее сообщение Следующее сообщение
  1. #1

    По умолчанию

    Ну отличия принципиального конечно нет, согласен, просто описал алгоритм, а по поводы "Сравнивать с нужными датами", это э какая простыня то получится расписанная, 12 месяцев, и черт его знает сколько лет, или я чего то не понимаю?

  2. #2
    Пользователь Аватар для petera
    Регистрация
    06.05.2011
    Адрес
    Минск
    Сообщений
    4,182

    По умолчанию

    Цитата Сообщение от Алексей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
    Мой канал на ютубе
    https://www.youtube.com/c/ПетрАртюков
    Мой канал на РУТУБЕ
    https://rutube.ru/channel/23641433/
    Библиотека ГМ для СП300
    https://disk.yandex.com/d/gHLMhLi8x1_HBg

  3. #3

    По умолчанию

    Цитата Сообщение от petera Посмотреть сообщение
    Все довольна просто будет, если перейти к переменным 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
    Огромное человеческое спасибо.

Похожие темы

  1. Обнуление счетчика МВ110-16ДН
    от nestor в разделе ПЛК3xx (архив)
    Ответов: 11
    Последнее сообщение: 11.08.2018, 16:21
  2. Обнуление регистра MODBUS RTU
    от Алексей Александрович в разделе ПЛК1хх
    Ответов: 1
    Последнее сообщение: 22.10.2014, 15:18
  3. Обнуление введенных параметров
    от Viktor40 в разделе Master SCADA 3
    Ответов: 5
    Последнее сообщение: 01.12.2011, 07:19
  4. обнуление при отсутсвии питания
    от Artem в разделе ПЛК1хх
    Ответов: 1
    Последнее сообщение: 03.09.2010, 20:08

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •