UnixTimeToFormat

Our dear Rex has already rewritten it seems all the universal functions for ROS Mikrotik …Here is Pepelxl’s function for converting timestamp time into human-readable time formats. I think it’s a little long. Is it possible to write it more rationally ?

input parameters $timestamp (unixtime) and $tmod (1-5)

usage: [$UnixTimeToFormat timeStamp=“unixtime” type=X]

type:

“unspecified” - month/dd/yyyy ((Mikrotik sheduller format)
1 - yyyy/mm/dd hh:mm:ss
2 - dd:mm:yyyy hh:mm:ss
3 - dd month yyy hh mm ss
4 - yyyy month dd hh mm ss
5 - month/dd/yyyy-hh:mm:ss (Mikrotik sheduller format)



:global UnixTimeToFormat do={
:local decodedLine ""
:local before false
:if ($timeStamp < 0) do={:set $before true; :set $timeStamp ($timeStamp * -1)}
:local timeS ($timeStamp % 86400)
:local timeH ($timeS / 3600)
:local timeM ($timeS % 3600 / 60)
:set $timeS ($timeS - $timeH * 3600 - $timeM * 60)

:local dateD ($timeStamp / 86400)
:local dateM 2
:local dateY 1970
:local leap false
:while (($dateD / 365) > 0) do={
:set $dateD ($dateD - 365)
:set $dateY ($dateY + 1)
:set $dateM ($dateM + 1) 
:if ($dateM = 4) do={:set $dateM 0
:if (($dateY % 400 = 0) or ($dateY % 100 != 0)) do={:set $leap true
:set $dateD ($dateD - 1)}} else={:set $leap false}}
:local months [:toarray (0,31,28,31,30,31,30,31,31,30,31,30,31)]
:if (leap) do={:set $dateD ($dateD + 1); :set ($months->2) 29}
do {
:for i from=1 to=12 do={:if (($months->$i) > $dateD) do={:set $dateM $i; :set $dateD ($dateD + 1); break;} else={:set $dateD ($dateD - ($months->$i))}}
} on-error={}

:local tmod 2
:local s "."
:local nf true
:local mstr {"jan";"feb";"mar";"apr";"may";"jun";"jul";"aug";"sep";"oct";"nov";"dec"}
:if ([:typeof $timeStruct] = "array") do={
:if ([:typeof ($timeStruct->"timeFormat")] = "num") do={:set $tmod ($timeStruct->"timeFormat")}
:if ([:typeof ($timeStruct->"dateSeparator")] = "str") do={:set $s ($timeStruct->"dateSeparator")}
:if ([:typeof ($timeStruct->"numFill")] = "bool") do={:set $nf ($timeStruct->"numFill")}
:if (([:typeof ($timeStruct->"monthsStr")] = "array") and ([:len ($timeStruct->"monthsStr")] = 12)) do={:set $mstr ($timeStruct->"monthsStr")}
}
:local strY [:tostr $dateY]
:local strMn
:local strD
:local strH
:local strM
:local strS
:if ($nf) do={
:if ($dateM > 9) do={:set $strMn [:tostr $dateM]} else={:set $strMn ("0".[:tostr $dateM])}
:if ($dateD > 9) do={:set $strD [:tostr $dateD]} else={:set $strD ("0".[:tostr $dateD])}
:if ($timeH > 9) do={:set $strH [:tostr $timeH]} else={:set $strH ("0".[:tostr $timeH])}
:if ($timeM > 9) do={:set $strM [:tostr $timeM]} else={:set $strM ("0".[:tostr $timeM])}
:if ($timeS > 9) do={:set $strS [:tostr $timeS]} else={:set $strS ("0".[:tostr $timeS])}
} else={
:set strMn [:tostr $dateM]
:set strD [:tostr $dateD]
:set strH [:tostr $timeH]
:set strM [:tostr $timeM]
:set strS [:tostr $timeS]
}
do {
:if ($tmod = 1) do={:set $decodedLine "$strY$s$strMn$s$strD $strH:$strM:$strS"; break;}
:if ($tmod = 2) do={:set $decodedLine "$strD$s$strMn$s$strY $strH:$strM:$strS"; break;}
:if ($tmod = 3) do={:set $decodedLine ("$strD ".($mstr->($dateM - 1))." $strY $strH:$strM:$strS"); break;}
:if ($tmod = 4) do={:set $decodedLine ("$strY ".($mstr->($dateM - 1))." $strD $strH:$strM:$strS"); break;}
} on-error={}
:return $decodedLine;
}

This convert all routeros datetime format to unix
:put [$datetime2epoch] no parameters = now
No matter the month case (not support absurd xxX, xXx or xXX format for maiusc.)
:put [$datetime2epoch “apr/13/2023 09:30:00”]
:put [$datetime2epoch “Apr/13/2023 09:30:00”]
:put [$datetime2epoch “APR/13/2023 09:30:00”]
:put [$datetime2epoch “apr/13 09:30:00”] (implicit current year, used on log and scheduler)
:put [$datetime2epoch “09:30:00”] (implicit current day/month/year, used on log and scheduler)

Added for compatibility with RouterOS v7.10+
:put [$datetime2epoch “2023-04-13 09:30:00”]
:put [$datetime2epoch “04-13 09:30:00”] (implicit current year, used on log and scheduler)

http://forum.mikrotik.com/t/calculate-the-difference-between-two-dates/162735/5


Convert unix time to datetime format?
http://forum.mikrotik.com/t/convert-uptime-to-date-and-time/157724/36
Just personalize the wanted output, easily a parameter can be added at the end to select the format.

This function converts unixtime to a human-readable date format. But only one. And it is necessary, as in Pepelxl, to make it possible to return the result in various formats:

1 - yyyy/mm/dd hh:mm:ss
2 - dd:mm:yyyy hh:mm:ss
3 - dd month yyy hh mm ss
4 - yyyy month dd hh mm ss
5 - month/dd/yyyy-hh:mm:ss (Mikrotik sheduller format)

Please do not uselessly repost scripts
If I update the script on the appropriate topic, bad or old versions are findable on search causing confuison.
The script is updated on forum with last version and bugfix, please remove the old you have posted.

Thanks.

month/dd/yyyy-hh:mm:ss (Mikrotik sheduller format)
???
a “-” between date and time? where???

Just join this
http://forum.mikrotik.com/t/convert-uptime-to-date-and-time/157724/36
with this
http://forum.mikrotik.com/t/changing-the-mmm-dd-yyyy-date-format/5183/10

For obtain this:

:global unixtodatetimeformatted do={
    :local ux [:tonum $1]
    :local Fzerofill do={:return [:pick (100 + $1) 1 3]}
    :local prMntDays [:toarray "0,0,31,59,90,120,151,181,212,243,273,304,334"]
    :local vgmt      [:tonum [/system clock get gmt-offset]]; :if ($vgmt > 0x7FFFFFFF) do={:set vgmt ($vgmt - 0x100000000)}
    :local gmtSg "+"; :if ($vgmt < 0) do={:set gmtSg "-"; :set vgmt ($vgmt * -1)}
    :local tzepoch   ($ux + $vgmt)
    :if ($tzepoch < 0) do={:set tzepoch 0} ; # unsupported negative unix epoch
    :local yearStart (1970 + ($tzepoch / 31536000))
    :local tmpbissex (($yearStart - 1968) / 4) ; :if ((($yearStart - 1968) % 4) = 0) do={:set ($prMntDays->1) -1 ; :set ($prMntDays->2) 30}
    :local tmpsec    ($tzepoch % 31536000)
    :local tmpdays   (($tmpsec / 86400) - $tmpbissex)
    :if (($tmpsec < (86400 * $tmpbissex)) and ((($yearStart - 1968) % 4) = 0)) do={
        :set tmpbissex ($tmpbissex - 1) ; :set ($prMntDays->1) 0 ; :set ($prMntDays->2) 31 ; :set tmpdays  ($tmpdays + 1)
    }
    :if ($tmpsec < (86400 * $tmpbissex)) do={:set yearStart ($yearStart - 1) ; :set tmpdays   ($tmpdays + 365)}
    :local mnthStart 12 ; :while (($prMntDays->$mnthStart) > $tmpdays) do={:set mnthStart ($mnthStart - 1)}
    :local dayStart  [$Fzerofill (($tmpdays + 1) - ($prMntDays->$mnthStart))]
    :local timeStart (00:00:00 + [:totime ($tmpsec % 86400)])

    :local vtime     $timeStart
    :local prMntDays [:toarray "0,0,31,59,90,120,151,181,212,243,273,304,334"]
    :local LcaseMnts [:toarray "0,jan,feb,mar,apr,may,jun,jul,aug,sep,oct,nov,dec"]
    :local PcaseMnts [:toarray "0,Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec"]
    :local UcaseMnts [:toarray "0,JAN,FEB,MAR,APR,MAY,JUN,JUL,AUG,SEP,OCT,NOV,DEC"]
    :local LcaseWeekDays [:toarray "thu,fri,sat,sun,mon,tue,wed"]
    :local PcaseWeekDays [:toarray "Thu,Fri,Sat,Sun,Mon,Tue,Wed"]
    :local UcaseWeekDays [:toarray "THU,FRI,SAT,SUN,MON,TUE,WED"]
    :local gmtHr [:pick [:totime $vgmt] 0 2]
    :local gmtMn [:pick [:totime $vgmt] 3 5]
    :local yyyy $yearStart
    :local Leap "No-Leap" ; :if ((($yyyy - 1968) % 4) = 0) do={:set Leap "Leap"; :set ($prMntDays->1) -1; :set ($prMntDays->2) 30}
    :local M    $mnthStart
    :local MM   [$Fzerofill $M]
    :local mmm  ($LcaseMnts->$M)
    :local Mmm  ($PcaseMnts->$M)
    :local MMM  ($UcaseMnts->$M)
    :local dd   $dayStart
    :local d    [:tonum $dd] ; :local totd ((($yyyy - 1970) * 365) + (($yyyy - 1968) / 4) + ($prMntDays->$M) + ($d - 1))
    :local www  ($LcaseWeekDays->($totd % 7))
    :local Www  ($PcaseWeekDays->($totd % 7))
    :local WWW  ($UcaseWeekDays->($totd % 7))
    :local HH   [:pick $vtime 0  2]
    :local H    [:tonum $HH]
    :local hh   ([:tonum $HH] % 12); :if ($hh = 0) do={:set hh 12}; :set hh [$Fzerofill $hh]
    :local h    [:tonum $hh]
    :local a    "A"; :if ([:tonum $HH] > 11) do={:set a "P"}
    :local aa   "$a\4D"
    :local mm   [:pick $vtime 3  5]
    :local m    [:tonum $mm]
    :local ss   [:pick $vtime 6  8]
    :local s    [:tonum $ss]
    :local Z    "$gmtSg$gmtHr:$gmtMn"

    :local out "$yyyy-$MM-$dd\54$HH:$mm:$ss$Z $Www $Leap"
    :if ($2 = "yyyy/mm/dd hh:mm:ss"   ) do={:set out "$yyyy/$MM/$dd $HH:$mm:$ss" }
    :if ($2 = "dd:mm:yyyy hh:mm:ss"   ) do={:set out "$dd:$MM:$yyyy $HH:$mm:$ss" }
    :if ($2 = "dd month yyy hh mm ss" ) do={:set out "$dd $mmm $yyyy $HH $mm $ss"}
    :if ($2 = "yyyy month dd hh mm ss") do={:set out "$yyyy $mmm $dd $HH $mm $ss"}
    :if ($2 = "Month/dd/yyyy hh:mm:ss") do={:set out "$Mmm/$dd/$yyyy $HH:$mm:$ss"}
    :return $out
}

> :put [$unixtodatetimeformatted 1681387492]
2023-04-13T14:04:52+02:00 Thu No-Leap

> :put [$unixtodatetimeformatted 1681387492 “yyyy/mm/dd hh:mm:ss”]
2023/04/13 14:04:52

> :put [$unixtodatetimeformatted 1681387492 “dd:mm:yyyy hh:mm:ss”]
13:04:2023 14:04:52

> :put [$unixtodatetimeformatted 1681387492 “dd month yyy hh mm ss”]
13 apr 2023 14 04 52

> :put [$unixtodatetimeformatted 1681387492 “yyyy month dd hh mm ss”]
2023 apr 13 14 04 52

> :put [$unixtodatetimeformatted 1681387492 “Month/dd/yyyy hh:mm:ss”]
Apr/13/2023 14:04:52
Just add the wanted formats at the end…

Thank you very much my friend !

I sent you functions from Osamahfarhan: http://forum.mikrotik.com/t/osamahfarhan-script-s-collection/165061/1
Weren’t they interested in you? There are functions that you haven’t written yet, such as a function to convert an array to JSON.
Maybe at your leisure you can shovel them into a normal shape (those that make sense to take from him)?

There is nothing in that list that is useful (and most of those I’ve already done better), and then, as already written in the other topic,
I certainly don’t bother correcting other people’s scripts, especially if they are written with feet and the variables called a,b,c,d,e,f…

As for converting from array to JSON, I’ve done this before, it can be the main engine, just change the text inside.

http://forum.mikrotik.com/t/iterate-over-all-elements-of-an-array-of-unknown-dimension/163033/19

As for converting from array to JSON, I’ve done this before, it can be the main engine, just change the text inside.

viewtopic.php?p=973362#p973367

I did not understand this. The code in this link can convert an array to JSON ?

If you already have something that loops through the array, just change the text around the variable names and values.

“alertList”: {
“0”: “arrayvalue1”,
“1”: “arrayvalue2”,
}
“audioSettings”: {
“DoP”: {
“title”: “DoP playback”,
“type”: “boolean”,
“value”: “false”,
}
“autoPlay”: {
“title”: “AutoPlay after boot”,
“type”: “boolean”,
“value”: “false”,
}
“soundCard”: {
“data”: {
“0”: {
“id”: “0”,
“name”: “Default”,
}
}
“title”: “Sound Card”,
“type”: “spinner”,
“value”: “0”,
}
“soundType”: {
“data”: {
“0”: {
“id”: “0”,
“name”: “Mono Differential”,
}
“1”: {
“id”: “1”,
“name”: “Stereo”,
}
}
“title”: “Sound Type”,
“type”: “spinner”,
“value”: “1”,
}
“title”: “Audio settings”,
}
“broadcastModeSettings”: {
“broadcastModeOptions”: {
“downloadURL”: “no URL provided”,
“streamURL”: “no URL provided”,
}
“broadcastType”: {
“data”: {
“0”: {
“id”: “0”,
“name”: “Default”,
}
“1”: {
“id”: “1”,
“name”: “Stream URL”,
}
“2”: {
“id”: “2”,
“name”: “Download URL”,
}
}
“title”: “Broadcast Type”,
“type”: “spinner”,
“value”: “0”,
}
“enabled”: “false”,
“title”: “Broadcast mode settings”,
}
“deviceInfo”: {
“autoUpgrade”: “true”,
“autoUpgradeInstall”: “true”,
“cpuTemp”: “48 C”,
“version”: “2.16.37”,
}
“multiroomSettings”: {
“masterMode”: “false”,
“slaveList”: {
“0”: “arrayvalue1”,
“1”: “arrayvalue2”,
}
}
“networkSettings”: {
“connections”: {
“LAN”: {
“addresses”: “192.168.0.101/24”,
“dns”: “192.168.0.1”,
“gateway”: “192.168.0.1”,
“method”: “auto”,
“state”: “connected”,
}
“WLAN”: {
“state”: “disconnected”,
}
}
“interfaces”: {
“LAN”: {
“title”: “Ethernet”,
“type”: “boolean”,
“value”: “true”,
}
“WLAN”: {
“title”: “Wi-Fi”,
“type”: “boolean”,
“value”: “false”,
}
}
“title”: “Network settings”,
“wifiList”:
}
And that’s just by changing the text here and there without changing the code.
A data type check should be integrated, to put the right brackets or quotes,
a check that does not put the comma if it is the last field,
and an (optional) control that indents the file for readability.

No one will write such a function except you. Chupaka disappeared completely. If there is time and mood, write a universal function for converting an array to JSON. It will be good for everyone. Can be used in /fetch.

You catch the point :wink:

A specialist like you should be freed from all other work and all conditions for work and good rest should be created. You alone can write many valuable scripts. And where is Mikrotik looking? If I were them, I’d give you a lifetime monthly bonus…

Thanks, that’s too much…