Создание дня недели, зная дату в Codesys
Очень плохо знакомы с Codesys, так что терпите меня. Я знаю, что вы можете использовать таймер, но по какой-то причине он не отображается в веб-визуализации. Таким образом, пытаясь найти функцию, которая будет отображать день недели, который соответствует выбранной дате. например. выберите 15.10.2018 и получите "понедельник"
2 ответа
В Википедии (на немецком) есть формула для расчета дня недели.
В CoDeSys:
PROGRAM PLC_PRG
VAR
d : INT:= 15; //day
m : INT:= 10; //month
y: INT:= 2018; //year
w: DINT; //result -> day of the week 1 = monday ...
END_VAR
Реализация:
w:= ((d + TRUNC(2.6 * ((m + 9) MOD 12 + 1) - 0.2) + y MOD 100 +
TRUNC(y MOD 100 / 4) + TRUNC(y / 400) - 2 * TRUNC(y / 100) - 1) MOD 7
+ 7) MOD 7 + 1;
Это возвращает день недели как число. 1 - понедельник, 2 - вторник и т. Д.
Это зависит от того, что у вас есть на входе. Если у вас есть месяц, день и год как отдельные INT
Значения приведенного выше примера могут работать. Но вы также можете преобразовать его в DATE
с которым гораздо лучше работать. Это позволит вам быстро перейти в TIME
или же TOD
и сравни даты и сделай намного больше.
VAR
DT: DATE;
Str: STRING;
d : INT:= 15; //day
m : INT:= 10; //month
y: INT:= 2018; //year
END_VAR
Str := CONCAT("D#", y);
Str := CONCAT(Str, '-');
Str := CONCAT(Str, m);
Str := CONCAT(Str, '-');
Str := CONCAT(Str, d);
(* Now our string is D#2018-10-15 *)
DT := STRING_TO_DATE(Str);
Если у вас есть тип DATE
Тогда вычислить день недели - очень тривиальная задача. Все, что нам нужно знать, это какой был день недели в тот или иной день. Затем мы можем посчитать, сколько дней мы с этого дня, разделить на 7 и получить MOD.
Вот факты, которые мы должны знать
- Внутреннее время хранения в секундах с 1 января 1970 года.
- Мы знаем, что 1 января 1970 года был четверг.
- 86400 секунд за один день
Вот пример функции.
FUNCTION WeekDay : UINT
VAR_INPUT
DT: DATE;
END_VAR
VAR
NumOfDays: DWORD;
END_VAR
(* How many days from 1 Jan. 1970 *)
NumOfDays := DATE_TO_DWORD(DT) / 86400;
WeekDay := DWORD_TO_UINT((NumOfDays + 3) MOD 7);
END_FUNCTION
+3 дают нам 0 - понедельник, потому что в системе, где 0 - понедельник, 3 - четверг, а если мы хотим 0 - воскресенье, мы можем использовать +4;
Конечно, вы можете оптимизировать функцию, чтобы быть только одна строка
WeekDay := DWORD_TO_UINT(((DATE_TO_DWORD(DT) / 86400) + 3) MOD 7);