Инструменты пользователя

Инструменты сайта


mikrotik:rb3011uias:routeros:system:scripts:functions:day_of_the_week

Это старая версия документа!


Функция вычисления дня недели по дате для MikroTik

Мой вариант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;

Вводим массивы с данными. Обратите внимание в каком порядке следуют дни недели и какая нумерация у месяцев. Так должно быть согласно алгоритму.

  :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;
}

Код для импорта

day-of-week.rsc
/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."

Пример использования

Т.к. функция глобальная, после запуска ее можно вызывать из любого другого скрипта или из терминала:

[vasya@Gateos] > :put [ $dayOfWeek ]
dec/08/2020
tue

Политики запуска

Это минимально необходимый набор для работы скрипта.

  • read,
  • write,
  • policy,
  • test.
1)
В Интернете есть несколько других кейсов, но все они показались мне несколько громоздкими и, по разным сообщениям, не всегда корректно работающим. Вот ссылки на них – раз, два и три. Поэтому я разобрался в работе алгоритма – Excel с примером – и собрал свой велосипед. LOL
2)
Подробнее смотрите по ссылке.
3)
При необходимости можно сделать функцию локальной, заменив :global на :local или вообще превратить в обычный фрагмент кода, убрав конструкцию :global dayOfWeek do={... :return $result; }.

Обсуждение

Ваш комментарий:
E P Y P T F F X V B G E I P G L
 
Последнее изменение: 2022/02/12 11:40 (внешнее изменение)