Информация
Услуги
  • Внедрение
  • Настройка
  • Поддержка
  • Ремонт
Контакты
Новинка
Распродажа
Новости
Доставка
Оплата
Загрузки
  • Прошивки
    • WinBox
    • RouterOS
    • Мобильные приложения MikroTik
    • Архив
  • Changelogs
  • RouterOS
  • Мобильные приложения MikroTik
  • Архив
Форум
Настройка
    info@mikrotik.moscow
    +7 495 320-55-52
    Заказать звонок
    Mikrotik.moscow
    Каталог
    • Акции
      Акции
    • Маршрутизаторы
      Маршрутизаторы
    • Коммутаторы
      Коммутаторы
    • Радиомосты и уличные точки доступа
      Радиомосты и уличные точки доступа
    • Wi-Fi для дома и офиса
      Wi-Fi для дома и офиса
    • LTE/5G
      LTE/5G
    • Powerline адаптеры
      Powerline адаптеры
    • IoT устройства
      IoT устройства
    • Оборудование 60 ГГц
      Оборудование 60 ГГц
    • Материнские платы RouterBOARD
      Материнские платы RouterBOARD
    • Корпуса
      Корпуса
    • Интерфейсы
      Интерфейсы
    • SFP/QSFP трансиверы
      SFP/QSFP трансиверы
    • Аксессуары
      Аксессуары
    • Антенны
      Антенны
    • Архив
      Архив
    Войти
    0 Сравнение
    0 Избранное
    0 Корзина
    Скачать WinBox Скачать Прошивки Форум > RouterOS Форум > SwOS Форум > Железо
    Mikrotik.moscow
    Каталог
    Войти
    0 Сравнение
    0 Избранное
    0 Корзина
    Mikrotik.moscow
    Телефоны
    +7 495 320-55-52
    Заказать звонок
    0
    0
    0
    Mikrotik.moscow
    • +7 495 320-55-52
      • Назад
      • Телефоны
      • +7 495 320-55-52
      • Заказать звонок
    • info@mikrotik.moscow
    • г. Москва, ул. Бакунинская, 84
    • Пн-Пт: 09-00 до 18-00
      Сб-Вс: выходной


    • Кабинет
    • 0 Сравнение
    • 0 Избранное
    • 0 Корзина
    Главная
    Форум
    RouterOS
    Сделал! Написал скрипт для вычисления UNIX time!

    Сделал! Написал скрипт для вычисления UNIX time!

    Форумы: RouterOS, Аппаратное обеспечение, SwOS, Обратная связь, Объявления, Сторонние инструменты
    Поиск  Пользователи  Правила  Войти
    Страницы: 1
    RSS
    Сделал! Написал скрипт для вычисления UNIX time!, RouterOS
     
    adeeadee
    Guest
    #1
    0
    07.08.2013 19:27:00
    Находишь этот скрипт полезным? Да Нет Может быть, не знаю 0 голосов.

    Привет! С версии 6.2 я пытаюсь создать скрипт для вычисления UNIX-времени (эпохальное время / POSIX-время) из текущей даты/времени RB. Скрипт содержит 2 функции: первая — JD, которая вычисляет Юлианские дни для указанной даты, а вторая — вычисляет UNIX-время на основе разницы между Юлианскими днями и Юлианской датой «01/01/1970». Думаю, он не идеален, но вот он:

    :global fncJD do={
    :local months [:toarray "jan,feb,mar,apr,may,jun,jul,aug,sep,oct,nov,dec"];
    :local jd
    :local M [:pick $1 0 3];
    :local D [:pick $1 4 6];
    :local Y [:pick $1 7 11];
    :for x from=0 to=([:len $months] - 1) do={
      :if ([:tostr [:pick $months $x]] = $M) do={:set M ($x + 1) }
      }
    :if ( $M = 1 || $M = 2) do={
       :set Y ($Y-1);
       :set M ($M+12);
    }
    :local A ($Y/100)
    :local B ($A/4)
    :local C (2-$A+$B)
    :local E ((($Y+4716) * 36525)/100)
    :local F ((306001*($M+1))/10000)
    :local jd ($C+$D+$E+$F-1525)
    :return $jd
    };

    :global timestamp do={
    :global fncJD $fncJD
    :local currtime [/system clock get time];
    :local jdnow [$fncJD [/system clock get date]]
    :local days ($jdnow - 2440587)
    :local ore [:pick $currtime 0 2]
    :local minute [:pick $currtime 3 5]
    :local secunde [:pick $currtime 6 8]
    :return (($days * 86400) + ($ore * 3600) + ($minute * 60) + $secunde - [/system clock get gmt-offset]);
    }

    После запуска скрипта просто объяви глобальную функцию в твоем скрипте и выполни:
    :global timestamp $timestamp
    :put [$timestamp]

    Можешь всегда предлагать предложения или улучшения этого скрипта.
     
     
     
    minks
    Guest
    #2
    0
    04.05.2020 16:48:00
    Конечно, я уже несколько лет создаю "крайне сжатую версию" для периода между 2000 и 2099 годами. Но для моих целей этого вполне достаточно =)
     
     
     
    Jotne
    Guest
    #3
    0
    04.05.2020 19:25:00
    Стоит сделать.
     
     
     
    januszzz
    Guest
    #4
    0
    30.10.2013 10:27:00
    Привет, значит, похоже, невозможно получить время в секундах с 1970-01-01 00:00:00 UTC напрямую в RouterOS? Нужно посчитать время сессии пользователей, а парсить время из rsyslog с точностью выше, чем дата +%s, сложнее.
     
     
     
    itnot
    Guest
    #5
    0
    28.12.2018 11:36:00
    Привет. Огромное спасибо adeeadee! Этот скрипт мне очень помог. Использую его, когда переношу данные GPS на сайт мониторинга. С уважением.
     
     
     
    zfuzesi
    Guest
    #6
    0
    26.04.2019 16:18:00
    Привет! Я работаю над скриптами автоматизации, которым также нужен unix timestamp. Вот мои предварительные функции:

    :global "parse_date" do={
     :local year [:pick $str 7 11]
     :local month [:find [:toarray "jan,feb,mar,apr,may,jun,jul,aug,sep,oct,nov,dec"] [:pick $str 0 3]]
     :local day [:pick $str 4 6]

     :set month ($month - 1)
     :if ($month <= 0) do={
       :set month ($month + 12)
       :set year ($year - 1)
     }

     :return ((
         365 * year + year / 4 - year / 100 + year / 400
       + 367 * month / 12 - 30
       + day - 1
       - 719527 + 31 + 28
       ) * 86400)
    }

    :global "parse_time" do={
     :local hour [:pick $str 0 2]
     :local min [:pick $str 3 5]
     :local sec [:pick $str 6 8]
     :return (hour * 3600 + min * 60 + sec)
    }

    :global "parse_timestamp" do={
     :global "parse_date"
     :global "parse_time"
     :return ([$"parse_date" str=[:pick $str 0 11]] + [$"parse_time" str=[:pick $str 12 20]])
    }

    :global "today" do={
     :global "parse_date"
     :return [$"parse_date" str=[/system clock get date]]
    }

    :global "time" do={
     :global "parse_time"
     :return [$"parse_time" str=[/system clock get time]]
    }

    :global "now" do={
     :global "today"
     :global "time"
     :return ([$"today"] + [$"time"])
    }
     
     
     
    minks
    Guest
    #7
    0
    04.05.2020 07:05:00
    Мой вариант epoch time, кажется, самый короткий =) :global EpochTime do={
      :local ds [/system clock get date];
      :local months;
      :if ((([:pick $ds 9 11]-1)/4) != (([:pick $ds 9 11])/4)) do={
         :set months {"an"=0;"eb"=31;"ar"=60;"pr"=91;"ay"=121;"un"=152;"ul"=182;"ug"=213;"ep"=244;"ct"=274;"ov"=305;"ec"=335};
      } else={
         :set months {"an"=0;"eb"=31;"ar"=59;"pr"=90;"ay"=120;"un"=151;"ul"=181;"ug"=212;"ep"=243;"ct"=273;"ov"=304;"dec"=334};
      }
      :set ds (([:pick $ds 9 11]*365)+(([:pick $ds 9 11]-1)/4)+($months->[:pick $ds 1 3])+[:pick $ds 4 6]);
      :local ts [/system clock get time];
      :set ts (([:pick $ts 0 2]*60*60)+([:pick $ts 3 5]*60)+[:pick $ts 6 8]);
      :return ($ds*24*60*60 + $ts + 946684800 - [/system clock get gmt-offset]);
    } Как использовать: :put [$EpochTime]
    1588575464
     
     
     
    Jotne
    Guest
    #8
    0
    04.05.2020 07:24:00
    Спасибо за скрипт. Я жаловался в техподдержку MikroTik по этому поводу. Подобные вещи должны быть встроены в RouterOS. Сейчас так невозможно работать со временем в RouterOS. Например, в CLI посмотрите на время в логах. Для событий, произошедших меньше 24 часа, отображается только время. Для событий, произошедших больше 24 часа, отображается месяц в тексте и дата + время. Как же тогда что-то рассчитывать по этому? Невозможно... Этот скрипт можно использовать для времени в логах? /log print detail time=apr/29 21:05:26 topics=system,error,critical message=“login failure for user xxxx from 192.168.10.178 via ssh” Мне бы хотелось видеть это время в формате epoc, а не apr/29 21:05:26.

    PS, не нужно ставить точку с запятой ; после каждой строки, только между несколькими командами в одной строке. Этот скрипт считает 2100 как високосный год, но это не так. Так далеко в будущем, что это не должно быть проблемой.
     
     
     
    Jotne
    Guest
    #9
    0
    04.05.2020 13:09:00
    Вот обновленная версия, которую можно использовать как для получения текущего времени, так и для преобразования данных из входных данных. Пример текущего времени: put [$EpochTime]
    1588597644 Преобразование времени: put [$EpochTime "may/01 16:23:50"]
    1588343030

    EpochTime "15:23:50"]
    1588598630 Если дата не указана, используется текущий день/месяц/год: global EpochTime do={
    # Использование
    # $EpochTime [входные данные времени]
    # -----
    # Получить текущее время
    # :put [$EpochTime]
    #
    # Прочитать время лога в одном из этих двух форматов "may/01 16:23:50" или "12:02:23" для номера лога *323
    # :put [$EpochTime [:log get *323 time]]

    :local ds
    :local ts
    :if ([:len $1]=0) do={
    # Получить "текущее время"
    :set ds [/system clock get date]
    :set ts [/system clock get time]
    } else={

    if ([:len $1]>8) do={
    # Использовать удаленную дату и время и преобразовать дату
    :set ds "$[:pick $1 0 6]/$[:pick [/system clock get date] 7 11]"
    :set ts [:pick $1 7 15]
    } else={
    # Использовать удаленное время и получить дату
    :set ds [/system clock get date]
    :set ts $1
    }
    }
    :local months
    :if ((([:pick $ds 9 11]-1)/4) != (([:pick $ds 9 11])/4)) do={

    :set months {"an"=0;"eb"=31;"ar"=60;"pr"=91;"ay"=121;"un"=152;"ul"=182;"ug"=213;"ep"=244;"ct"=274;"ov"=305;"ec"=335}
    } else={
    :set months {"an"=0;"eb"=31;"ar"=59;"pr"=90;"ay"=120;"un"=151;"ul"=181;"ug"=212;"ep"=243;"ct"=273;"ov"=304;"ec"=334}
    }
    :set ds (([:pick $ds 9 11]*365)+(([:pick $ds 9 11]-1)/4)+($months->[:pick $ds 1 3])+[:pick $ds 4 6])
    :set ts (([:pick $ts 0 2]*60*60)+([:pick $ts 3 5]*60)+[:pick $ts 6 8])
    :return ($ds*24*60*60 + $ts + 946684800 - [/system clock get gmt-offset])
    } НБ, не уверен, как это обрабатывает лог вокруг смены года, когда год отсутствует. НБ временной лаг год 2100, 2200 и т.д. не обрабатываются. Но это не должно быть проблемой.
     
     
     
    colin
    Guest
    #10
    0
    21.06.2020 14:05:00
    “dec” в этой строке: else={
       :set months {"an"=0;"eb"=31;"ar"=59;"pr"=90;"ay"=120;"un"=151;"ul"=181;"ug"=212;"ep"=243;"ct"=273;"ov"=304;"dec"=334}
    } нужно заменить на “ec”: else={
       :set months {"an"=0;"eb"=31;"ar"=59;"pr"=90;"ay"=120;"un"=151;"ul"=181;"ug"=212;"ep"=243;"ct"=273;"ov"=304;"ec"=334}
    }
     
     
     
    Jotne
    Guest
    #11
    0
    21.06.2020 14:35:00
    Отличный улов, исправил исходный пост.
     
     
     
    rextended
    Guest
    #12
    0
    01.09.2021 21:42:00
    Поиск тега #rextended mikrotik date to ISO:8601 date date2iso epoch unix time week day date2epoch date2weekday. Это первая попытка переписать функцию для преобразования данных "get date, time and gmt-offset" с Mikrotik в валидный формат ISO:8601, например, 2021-09-01T21:10:26+00:00 (Великобритания) = 2021-09-01T21:10:26Z (UTC) = 2021-09-01T23:10:26+02:00 (Италия).  Полученная дата возвращается со строчными месяцами, тогда как дата в файле – с заглавными, и т.д. Вместо этого в логах – дата последнего доступа пользователя, дата отключения/подключения канала, строки в логах и прочее начинается с заглавной буквы (приятное решение – убрать первую букву при сравнении, вероятно, я сделаю то же самое позже).  Программисты MikroTik не любят единообразие… Как, например, три разных формата даты в логах? Почему бы не использовать международную дату 2021-09-01??? Там понятно, где год, месяц и день… Я всегда использую `global` в этих примерах, чтобы быстро работать в терминале, а в скрипте заменяю все вхождения `global` на `local` /system clock
    :global strDate [get date]
    :global strTime [get time]
    :global intGoff [:tonum [get gmt-offset]]
    :if ($intGoff > 0x7FFFFFFF) do={:set intGoff ($intGoff - 0x100000000)}
    :global arrMonths {jan="01";feb="02";mar="03";apr="04";may="05";jun="06";jul="07";aug="08";sep="09";oct="10";nov="11";dec="12"}
    :global intYear   [:tonum [:pick $strDate 7 11]]
    :global strMonth  ($arrMonths->[:pick $strDate 0 3])
    :global strDay    [:pick $strDate 4 6]
    :global strHour   [:pick $strTime 0 2]
    :global strMinute [:pick $strTime 3 5]
    :global strSecond [:pick $strTime 6 8]
    :global strOffsig "+"
    :global strGoff   $intGoff
    :if ($intGoff < 0) do={:set strOffsig "-"; :set strGoff ($intGoff * -1)}
    :global strHoff  [:pick [:totime $strGoff] 0 2]
    :global strMoff  [:pick [:totime $strGoff] 3 5]
    :global strISOdate "$intYear-$strMonth-$strDay\54$strHour:$strMinute:$strSecond$strOffsig$strHoff:$strMoff"
    :put "$strDate $strTime $strOffsig$intGoff converted to ISO format is $strISOdate" (EDIT later: upgraded version of this script https://forum.mikrotik.com/viewtopic.php?p=960070#p960070) и после этого, скрипт рассчитывает “epoch” время в формате UNIX. Это продолжение роутерборда. Я не считаю секунды часового пояса, так как на момент написания не существует часовых поясов с “секундами”. Скрипт включает расчет високосного года и день недели. Точный расчет до 2100 года, но, вероятно, к тому времени всех нас уже не будет. Эх… :global arrPreMonDays {"01"=0;"02"=31;"03"=59;"04"=90;"05"=120;"06"=151;"07"=181;"08"=212;"09"=243;"10"=273;"11"=304;"12"=334}
    # 1970-01-01 is a Thursday
    :global arrWeekDays   {"Thu";"Fri";"Sat";"Sun";"Mon";"Tue";"Wed"}
    # first bixestile year immediately before 1970 is 1968
    :global numTotalDays  (($intYear - 1968) / 4)
    :global bolLeapYear   false
    :if ((($intYear - 1968) % 4) = 0) do={:set bolLeapYear true; :set ($arrPreMonDays->"01") -1; :set ($arrPreMonDays->"02") 30}
    :set numTotalDays  ($numTotalDays + (($intYear - 1970) * 365))
    :set numTotalDays  ($numTotalDays + ($arrPreMonDays->$strMonth))
    :set numTotalDays  ($numTotalDays + ([:tonum $strDay] - 1))
    :global strWeekDay ($arrWeekDays->($numTotalDays % 7))
    :global numTotHours   (($numTotalDays * 24) + [:tonum $strHour])
    :global numTotMinutes (($numTotHours * 60) + [:tonum $strMinute])
    :global numTotSeconds (($numTotMinutes * 60) + [:tonum $strSecond] - $intGoff)
    :put "For $strISOdate UNIX time is $numTotSeconds the current year is a lap year:$bolLeapYear and the Week Day is $strWeekDay" (EDIT later: upgraded version of this script https://forum.mikrotik.com/viewtopic.php?p=960070#p960070) Следующий шаг – преобразовать все в три отдельные функции: date2iso, date2epoch, date2weekday. Функция для проверки, является ли год високосным или нет, не нужна. (просто проверьте, верно ли ((($checkYear - 1968) % 4) = 0) или нет) Функции уже должны внутренне проверять, является ли переданная дата допустимой, и принимать любой “тип формата лога”.
     
     
     
    Jotne
    Guest
    #13
    0
    02.09.2021 05:29:00
    Тебе правда нужны все эти глобальные переменные, нельзя ли использовать локальные?
     
     
     
    rextended
    Guest
    #14
    0
    02.09.2021 06:57:00
    Я вообще не понимаю, я уже писал, что всегда использую `global` в этих примерах, чтобы быстро работать в терминале, а в скрипте заменяю все `global` на `local`. Вы имеете в виду, что `local` нельзя использовать, а `global` нельзя заменить в скрипте?
     
     
     
    Jotne
    Guest
    #15
    0
    02.09.2021 08:43:00
    Слишком рано утром, чтобы всё это читать.
     
     
     
    rextended
    Guest
    #16
    0
    02.09.2021 14:17:00
    search tag # rextended lowercase uppercase chr2lcase chr2ucase Функции для преобразования одного символа в нижний и верхний регистр. Любые другие символы, переданные в качестве аргумента, остаются без изменений.

    :global chr2lcase do={
       :local charsString ""
       :for x from=0 to=15 step=1 do={ :for y from=0 to=15 step=1 do={
           :local tmpHex "$[:pick "0123456789ABCDEF" $x ($x+1)]$[:pick "0123456789ABCDEF" $y ($y+1)]"
           :set $charsString "$charsString$[[:parse "(\"\\$tmpHex\")"]]"
       } }
       :local chrValue [:find $charsString $1 -1]
       :if (($chrValue > 64) and ($chrValue < 91)) do={
           :return [:pick $charsString ($chrValue + 32) ($chrValue + 33)]
       } else={
           :return $1
       }
    }

    :global chr2ucase do={
       :local charsString ""
       :for x from=0 to=15 step=1 do={ :for y from=0 to=15 step=1 do={
           :local tmpHex "$[:pick "0123456789ABCDEF" $x ($x+1)]$[:pick "0123456789ABCDEF" $y ($y+1)]"
           :set $charsString "$charsString$[[:parse "(\"\\$tmpHex\")"]]"
       } }
       :local chrValue [:find $charsString $1 -1]
       :if (($chrValue > 96) and ($chrValue < 123)) do={
           :return [:pick $charsString ($chrValue - 32) ($chrValue - 31)]
       } else={
           :return $1
       }
    } :put [$chr2lcase “A”] :put [$chr2ucase “a”]
     
     
     
    rextended
    Guest
    #17
    0
    15.03.2023 10:16:00
    Поисковый тег #rextended
    str2case: функции для преобразования строки в нижний регистр, верхний регистр или с заглавной буквой (только первая буква заглавная, остальные строчные). Любые другие символы, отличные от A-Z a-z, остаются без изменений. Необязательный параметр: без параметра преобразует первую букву в верхний регистр, а все остальные – в нижний. "U" – преобразовать в верхний регистр, "L" – преобразовать в нижний регистр, "P" – преобразовать в строку с заглавной буквой (только первая буква в каждом слове заглавная, остальные строчные).
    :global str2case do={
       :local input [:tostr "$1"]
       :local options "$2"
       :local letters "[A-Za-z]"

       :local charsString ""
       :for x from=0 to=15 step=1 do={ :for y from=0 to=15 step=1 do={
           :local tmpHex "$[:pick "0123456789ABCDEF" $x ($x+1)]$[:pick "0123456789ABCDEF" $y ($y+1)]"
           :set $charsString "$charsString$[[:parse "(\"\\$tmpHex\")"]]"
       } }

       :local position 0 ; :local chrValue 0; :local what "U" ; :local output "" ; :local work "" ; :local previous ""
       :while ($position < [:len $input]) do={
           :set work [:pick $input $position ($position + 1)]
           :set chrValue [:find $charsString $work -1]
           :if ($options~"(p|P)") do={:set what "U"}
           :if (($options~"(l|L)") or ((!($options~"(l|L|u|U)")) and ($previous~$letters))) do={:set what "L"}
           :if (($what = "L") and (($chrValue > 64) and ($chrValue <  91))) do={
               :set work [:pick $charsString ($chrValue + 32) ($chrValue + 32 + 1)]
           }
           :if (($what = "U") and (($chrValue > 96) and ($chrValue < 123))) do={
               :set work [:pick $charsString ($chrValue - 32) ($chrValue - 32 + 1)]
           }
           :set output "$output$work"
           :set previous $work
           :set position ($position + 1)
       }
       :return $output
    } > :put [$str2case “this iS a teSt ,a teSt is it”] This is a test ,a test is it > :put [$str2case “this iS a teSt ,a teSt is it” “U”] THIS IS A TEST ,A TEST IS IT > :put [$str2case “this iS a teSt ,a teSt is it” “L”] this is a test ,a test is it > :put [$str2case “this iS a teSt ,a teSt is it” “P”] This Is A Test ,A Test Is It
     
     
     
    diamuxin
    Guest
    #18
    0
    15.03.2023 12:20:00
    Интересно, спасибо! Я попробовал, и здесь что-то не так: [] > :put [$str2case "this iS a teSt ,a teSt is it"]
    "this iS a teSt ,a teSt is it" U и L работают нормально. BR.
     
     
     
    Страницы: 1
    Читают тему
    +7 495 320-55-52
    info@mikrotik.moscow
    Электрозаводская, Бауманская
    Москва, ул. Бакунинская, 84с21
    Конфиденциальность Оферта
    © 2026 «Mikrotik.Moscow»
    Главная Каталог 0 Корзина 0 Избранные Кабинет 0 Сравнение Акции Контакты Услуги Бренды Отзывы Компания Лицензии Документы Реквизиты Поиск Блог Обзоры