Это старая версия документа!
Мой вариант1) функции, которая возвращает текущий день недели основываясь на дате. Использует модифицированный алгоритм Зеллера для программного обеспечения2).
Добавлена модифицированная функция, которая возвращает массив из дня недели и текущего часа.
Создаем глобальную функцию3) и получаем текущую дату.
:global dayOfWeek do={
:local date [ /system clock get date ];
Для тестирования и диагностики закомментировать предыдущее и раскомментировать это. Дату указывать, как в примере.
#:local date "mar/01/2009"; #:put $date;
Инициализируем необходимые переменные.
:local result; :local day; :local year;
<BOOKMARK:days-array>Вводим массивы с данными. Обратите внимание в каком порядке следуют дни недели и какая нумерация у месяцев. Так должно быть согласно алгоритму.
:local days {"sat";"sun";"mon";"tue";"wed";"thu";"fri";};
:local months {mar="3";apr="4";may="5";jun="6";jul="7";aug="8";sep="9";oct="10";nov="11";dec="12";jan="13";feb="14";};
Отбираем месяц и «век».
:local month ( $months -> [ :pick $date 0 3 ] ); :local century [ :pick $date 7 9 ];
Проверяем день и год – если они начинаются с нуля, используем только вторую цифру.
:if ( [ :pick $date 4 5 ] = 0 ) do={ :set day [ :pick $date 5 6 ]; } else={ :set day [ :pick $date 4 6 ]; }
:if ( [ :pick $date 9 10 ] = 0 ) do={ :set year [ :pick $date 10 11 ]; } else={ :set year [ :pick $date 9 11 ]; }
Корректируем номер года для Января и Февраля, т.к., согласно алгоритму, они имеют номера 13 и 14 соответственно.
:if ( $month = 13 || $month = 14 ) do={ :set year ( $year - 1 ); }
Сам модифицированный алгоритм Зеллера.
:set result ( $day + ( 13 * ( $month + 1 ) / 5 ) + ( $century / 4 ) + $year + ( $year / 4 ) + ( 5 * $century ) ); :set result ( $days -> ( $result % 7 ) );
Возвращаем результат.
:return $result; }
/system script
add comment="\D4\F3\ED\EA\F6\E8\FF \E2\FB\F7\E8\F1\EB\E5\ED\E8\FF \E4\ED\FF \
\ED\E5\E4\E5\EB\E8" dont-require-permissions=no name=day-of-week owner=\
vasya policy=read,write,policy,test source="# Written by Nikolay Soloshin \
(nikolay@soloshin.su) for RouterOS v6.47.8 on hAP (mipsbe) @ 2020.12\r\
\n\r\
\n:global dayOfWeek do={\r\
\n :local date [ /system clock get date ];\r\
\n\r\
\n # For test\r\
\n #:local date \"mar/01/2009\";\r\
\n #:put \$date;\r\
\n\r\
\n :local result;\r\
\n :local day;\r\
\n :local year;\r\
\n\r\
\n :local days {\"sat\";\"sun\";\"mon\";\"tue\";\"wed\";\"thu\";\"fri\";}\
;\r\
\n :local months {mar=\"3\";apr=\"4\";may=\"5\";jun=\"6\";jul=\"7\";aug=\
\"8\";sep=\"9\";oct=\"10\";nov=\"11\";dec=\"12\";jan=\"13\";feb=\"14\";};\
\r\
\n\r\
\n :local month ( \$months -> [ :pick \$date 0 3 ] );\r\
\n :local century [ :pick \$date 7 9 ];\r\
\n\r\
\n # If the first char is a 0 (zero) only read last char, else script fai\
ls\r\
\n :if ( [ :pick \$date 4 5 ] = 0 ) do={ :set day [ :pick \$date 5 6 ]; }\
\_else={ :set day [ :pick \$date 4 6 ]; }\r\
\n :if ( [ :pick \$date 9 10 ] = 0 ) do={ :set year [ :pick \$date 10 11 \
]; } else={ :set year [ :pick \$date 9 11 ]; }\r\
\n \r\
\n # Adjusting the year value for January and February\r\
\n :if ( \$month = 13 || \$month = 14 ) do={ :set year ( \$year - 1 ); }\
\r\
\n\r\
\n # Modified Zeller's congruence for software\r\
\n :set result ( \$day + ( 13 * ( \$month + 1 ) / 5 ) + ( \$century / 4 )\
\_+ \$year + ( \$year / 4 ) + ( 5 * \$century ) );\r\
\n :set result ( \$days -> ( \$result % 7 ) );\r\
\n\r\
\n :return \$result;\r\
\n}\r\
\n\r\
\n# With love from Vladivostok."
Модифицированная функция, которая возвращает массив из цифры дня недели и цифры часа. НАПИСАТЬ, ГДЕ ВВОДИТСЯ И ГДЕ ИСПОЛЬЗУЕТСЯ,
Этот код содержит такие изменения:
Получение часа из текущего времени и преобразование строки в число.
:local time [ :tonum [ :pick [ /system clock get time ] 0 2 ] ];
Строка для тестирования.
#:local time [ :tonum 14 ];
Удаление нуля в первой позиции из времени.
:if ( [ :pick $time 0 1 ] = 0 ) do={ :set time [ :pick $time 0 1 ]; }
Сборка массива.
:set ( $result -> "day" ) $day; :set ( $result -> "time" ) $time;
Добавлено преобразование в массив.
:local result [ :toarray "" ];
Убрана трансформация в буквенный код дня недели.
:set day ( $day % 7 );
Этот массив больше не нужен, т.к. отдаем в виде цифры.
:local days {"sat";"sun";"mon";"tue";"wed";"thu";"fri";};
/system script
add comment="\CC\EE\E4\E8\F4\E8\EA\E0\F6\E8\FF, \E2\EE\E7\E2\F0\E0\F9\E0\FE\F9\
\E0\FF \E4\E5\ED\FC \ED\E5\E4\E5\EB\E8 \E8 \E2\F0\E5\EC\FF" \
dont-require-permissions=no name=day-of-week-and-time owner=vasya policy=\
ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon source=":\
global dayAndTime do={\r\
\n :local date [ /system clock get date ];\r\
\n :local time [ :tonum [ :pick [ /system clock get time ] 0 2 ] ];\r\
\n\r\
\n # For test\r\
\n #:local time [ :tonum 14 ];\r\
\n #:local date \"mar/01/2009\";\r\
\n\r\
\n :local day;\r\
\n :local year;\r\
\n :local result [ :toarray \"\" ];\r\
\n\r\
\n :local months {mar=\"3\";apr=\"4\";may=\"5\";jun=\"6\";jul=\"7\";aug=\
\"8\";sep=\"9\";oct=\"10\";nov=\"11\";dec=\"12\";jan=\"13\";feb=\"14\";};\
\r\
\n\r\
\n :local month ( \$months -> [ :pick \$date 0 3 ] );\r\
\n :local century [ :pick \$date 7 9 ];\r\
\n\r\
\n # If the first char is a 0 (zero) only read last char, else script fai\
ls\r\
\n :if ( [ :pick \$date 4 5 ] = 0 ) do={ :set day [ :pick \$date 5 6 ]; }\
\_else={ :set day [ :pick \$date 4 6 ]; }\r\
\n :if ( [ :pick \$date 9 10 ] = 0 ) do={ :set year [ :pick \$date 10 11 \
]; } else={ :set year [ :pick \$date 9 11 ]; }\r\
\n :if ( [ :pick \$time 0 1 ] = 0 ) do={ :set time [ :pick \$time 0 1 ]; \
}\r\
\n \r\
\n # Adjusting the year value for January and February\r\
\n :if ( \$month = 13 || \$month = 14 ) do={ :set year ( \$year - 1 ); }\
\r\
\n\r\
\n # Modified Zeller's congruence for software\r\
\n :set day ( \$day + ( 13 * ( \$month + 1 ) / 5 ) + ( \$century / 4 ) + \
\$year + ( \$year / 4 ) + ( 5 * \$century ) );\r\
\n :set day ( \$day % 7 );\r\
\n\r\
\n :set ( \$result -> \"day\" ) \$day;\r\
\n :set ( \$result -> \"time\" ) \$time;\r\
\n\r\
\n :return \$result;\r\
\n}"
Т.к. функции глобальные, после запуска их можно вызывать из любого другого скрипта или из терминала.
Вывод оригинальной функции:
[vasya@Gateos] > :put [ $dayOfWeek ] dec/08/2020 tue
Вывод модифицированной функции:
[vasya@Gateos] > :put [ $dayAndTime ] dec/08/2020 18:29:37 day=3;time=18
Порядок следования дней недели смотрите выше.
Это минимально необходимый набор для работы функции.
:global на :local или вообще превратить в обычный фрагмент кода, убрав конструкцию :global dayOfWeek do={... :return $result; }.
Обсуждение