Community discussions

MikroTik App

Do you find this script useful?

Poll ended at Tue Nov 05, 2013 9:27 pm

Yes
No votes
No
No votes
Maybe
1 (100%)
I don't know
No votes
 
Total votes: 1
 
adeeadee
just joined
Topic Author
Posts: 4
Joined: Sun Aug 21, 2011 8:23 pm

I did it! Script to compute UNIX time!

Wed Aug 07, 2013 10:27 pm

Hi there.
Since version 6.2 I try to make a script to compute the UNIX time (epoch time / posix time) from RB current date/time.
The script contains 2 functions: first one is JD which calculates Julian Days for specified date and the second one calculates the unix time based on difference between Julian Days and Julian date of 'jan/01/1970'.
I guess is not flawless, but here it is 8) :
: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]);
}
After running the script just declare global function in your script and execute:
:global timestamp $timestamp
:put [$timestamp]
You can always post suggestions or enhancements to this script.
Last edited by adeeadee on Thu Aug 08, 2013 9:35 am, edited 1 time in total.
 
User avatar
boen_robot
Forum Guru
Forum Guru
Posts: 2400
Joined: Thu Aug 31, 2006 4:43 pm
Location: europe://Bulgaria/Plovdiv

Re: I did it! Script to compute UNIX time!

Wed Aug 07, 2013 10:41 pm

But why are you using Julian date as opposed to Gregorian?

Also, since 6.2 allows functions to accept arguments and :return, consider using that capability, since a timestamp is generally something to be used as part of a greater whole.
 
adeeadee
just joined
Topic Author
Posts: 4
Joined: Sun Aug 21, 2011 8:23 pm

Re: I did it! Script to compute UNIX time!

Wed Aug 07, 2013 10:46 pm

Julian date is the simplest algorithm I found that can be implemented to RouterOS in order to compute days since 1970.
 
januszzz
Member Candidate
Member Candidate
Posts: 105
Joined: Wed Oct 07, 2009 9:17 pm

Re: I did it! Script to compute UNIX time!

Wed Oct 30, 2013 12:27 pm

Hello,

so I guess its impossible to get the time in seconds since 1970-01-01 00:00:00 UTC in any current RouterOS directly?

I need to count users' session time and parsing rsyslog precision time is harder than log in date +%s.
 
itnot
just joined
Posts: 2
Joined: Mon Aug 29, 2016 9:02 pm

Re: I did it! Script to compute UNIX time!

Fri Dec 28, 2018 1:36 pm

Hello.

Many thanks to adeeadee.

This script was useful to me.
I use it when transferring GPS data to the monitoring site.

Regards,
 
zfuzesi
just joined
Posts: 1
Joined: Thu Aug 16, 2018 2:00 pm

Re: I did it! Script to compute UNIX time!

Fri Apr 26, 2019 7:18 pm

Hello, I'm working on automation scripts that also need unix timestamp. Here are my preliminary functions:
: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
just joined
Posts: 13
Joined: Sun Feb 23, 2020 10:05 pm
Contact:

Re: I did it! Script to compute UNIX time!

Mon May 04, 2020 10:05 am

My variant of epoch time, seems the shortest =)
: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]);
}
How to use:

:put [$EpochTime] 
1588575464
 
User avatar
Jotne
Forum Guru
Forum Guru
Posts: 3292
Joined: Sat Dec 24, 2016 11:17 am
Location: Magrathean

Re: I did it! Script to compute UNIX time!

Mon May 04, 2020 10:24 am

Thanks for the script.
This is some I have complained to MT support about. Some like this should be built in to the RouterOS software.
As it is now, its impossible to handle time in RouterOS.
Example: From Cli, look at log time. For event less then 24 hour, only time is shown.
For event more than 24, moth in text and date + time is shown. How to then calculate some from this. Impossible..

Could this script be used for Log time as well?
/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"
I would lime this time in epoc and not apr/29 21:05:26

PS, you do not need semicolon ; after each line, only between multiple commands on same lines.
This script sets 2100 as a leap year, but it is not. So far inn to the future that it should not be a problem :)
 
User avatar
Jotne
Forum Guru
Forum Guru
Posts: 3292
Joined: Sat Dec 24, 2016 11:17 am
Location: Magrathean

Re: I did it! Script to compute UNIX time!

Mon May 04, 2020 4:09 pm

Here is an updated version that could be used to both get current time or convert data from input.

Example current time
:put [$EpochTime]
1588597644
Convert time
:put [$EpochTime "may/01 16:23:50"]
1588343030

EpochTime "15:23:50"]
1588598630
When date not give, it uses current day/month/year

:global EpochTime do={
	# Usage
	# $EpochTime [time input]
	# -----
	# Get current time
	# :put [$EpochTime]
	# 
	# Read log time in one of these two format "may/01 16:23:50" or "12:02:23" for log number *323
	# :put [$EpochTime [:log get *323 time]]

	:local ds
	:local ts
	:if ([:len $1]=0) do={
		# Get "now time"
		:set ds [/system clock get date]
		:set ts [/system clock get time]
	} else={
	
		if ([:len $1]>8) do={
			# Use remote date and time and convert date
			:set ds "$[:pick $1 0 6]/$[:pick [/system clock get date] 7 11]"
			:set ts [:pick $1 7 15]
		} else={
			# Use remote time and get date
			: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])
}
NB, not sure how it handles log around new year change, when year is missing.
NB time laps year 2100, 2200 etc are not handled. But should not be a problem ;)
Last edited by Jotne on Thu Sep 02, 2021 8:31 am, edited 2 times in total.
 
minks
just joined
Posts: 13
Joined: Sun Feb 23, 2020 10:05 pm
Contact:

Re: I did it! Script to compute UNIX time!

Mon May 04, 2020 7:48 pm

Of course,
i'm create the "shortest variant" for years between 2000 and 2099.
But for my purpose it's enough =)
 
User avatar
Jotne
Forum Guru
Forum Guru
Posts: 3292
Joined: Sat Dec 24, 2016 11:17 am
Location: Magrathean

Re: I did it! Script to compute UNIX time!

Mon May 04, 2020 10:25 pm

Should do :)
 
colin
Frequent Visitor
Frequent Visitor
Posts: 74
Joined: Mon May 11, 2015 11:11 am

Re: I did it! Script to compute UNIX time!

Sun Jun 21, 2020 5:05 pm

Here is an updated version that could be used to both get current time or convert data from input.

Example current time
:put [$EpochTime]
1588597644
Convert time
:put [$EpochTime "may/01 16:23:50"]
1588343030

EpochTime "15:23:50"]
1588598630
When date not give, it uses current day/month/year

:global EpochTime do={
	# Usage
	# $EpochTime [time input]
	# -----
	# Get current time
	# :put [$EpochTime]
	# 
	# Read log time in one of these two format "may/01 16:23:50" or "12:02:23" for log number *323
	# :put [$EpochTime [:log get *323 time]]

	:local ds
	:local ts
	if ([:len $1]=0) do={
		# Get "now time"
		:set ds [/system clock get date]
		:set ts [/system clock get time]
	} else={
	
		if ([:len $1]>8) do={
			# Use remote date and time and convert date
			:set ds "$[:pick $1 0 6]/$[:pick [/system clock get date] 7 11]"
			:set ts [:pick $1 7 15]
		} else={
			# Use remote time and get date
			: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;"dec"=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])
}
NB, not sure how it handles log around new year change, when year is missing.
NB time laps year 2100, 2200 etc are not handled. But should not be a problem ;)

"dec" in this line:
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}
}
should be "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}
}
 
User avatar
Jotne
Forum Guru
Forum Guru
Posts: 3292
Joined: Sat Dec 24, 2016 11:17 am
Location: Magrathean

Re: I did it! Script to compute UNIX time!

Sun Jun 21, 2020 5:35 pm

Good catch, fixed the original post.
 
User avatar
rextended
Forum Guru
Forum Guru
Posts: 11982
Joined: Tue Feb 25, 2014 12:49 pm
Location: Italy
Contact:

Re: I did it! Script to compute UNIX time!

Thu Sep 02, 2021 12:42 am

search tag # rextended mikrotik date to ISO:8601 date date2iso epoch unix time week day date2epoch date2weekday

A first pass to rewrite the function, is try to convert mikrotik "get date, time and gmt-offset" to valid ISO:8601 date like
2021-09-01T21:10:26+00:00 (Great Britain) = 2021-09-01T21:10:26Z (UTC) = 2021-09-01T23:10:26+02:00 (Italy)

The get date return lowercase months name, the date on file is with months on lowercase, etc.
instead last user access date, last link down/link up, date on log lines, and other, start with first letter uppercase,
(nice solution remove first letter on compare, probably I do the same later)
MikroTik programmers do not like uniformity.... Like 3 different type of date on logs....
Why do not use international date 2021-09-01??? Is clear where is the year, the month and the day...

I everytime use global on that examples for rapidly work on terminal, on script replace all "global" occurencies with "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 viewtopic.php?p=960070#p960070 )

and after that, this is an addon to calculate UNIX "epoch" time. This cont timezione of the routerboard.
I do not count TimeZone seconds because, at the time I write, do not exist any timezone with "seconds"
The script include the calculaton of lap year and the week day.
Still precise until 2100, but probably at that date we are all dead. Eh...
: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 viewtopic.php?p=960070#p960070 )


Next step is convert all to 3 single functions: date2iso, date2epoch, date2weekday.
Function to check if year is leap year or not is useless. (simply check if this ((($checkYear - 1968) % 4) = 0) is true or not)
The functions already internally must check if the passed date is valid or not,
and accept any "log format type".
Last edited by rextended on Thu May 11, 2023 3:37 am, edited 9 times in total.
 
User avatar
Jotne
Forum Guru
Forum Guru
Posts: 3292
Joined: Sat Dec 24, 2016 11:17 am
Location: Magrathean

Re: I did it! Script to compute UNIX time!

Thu Sep 02, 2021 8:29 am

Do you need all these global variable, cant local be used.
 
User avatar
rextended
Forum Guru
Forum Guru
Posts: 11982
Joined: Tue Feb 25, 2014 12:49 pm
Location: Italy
Contact:

Re: I did it! Script to compute UNIX time!

Thu Sep 02, 2021 9:57 am

Do you need all these global variable, cant local be used.
I do not understand :( ,
I already wrote
I everytime use global on that examples for rapidly work on terminal, on script replace all "global" occurencies with "local"
You mean than local can't be used, global can't be replaced on script?
 
User avatar
Jotne
Forum Guru
Forum Guru
Posts: 3292
Joined: Sat Dec 24, 2016 11:17 am
Location: Magrathean

Re: I did it! Script to compute UNIX time!

Thu Sep 02, 2021 11:43 am

Its to early in the morning to read all :)
😎 👍
 
User avatar
rextended
Forum Guru
Forum Guru
Posts: 11982
Joined: Tue Feb 25, 2014 12:49 pm
Location: Italy
Contact:

Re: I did it! Script to compute UNIX time!

Thu Sep 02, 2021 5:17 pm

search tag # rextended lowercase uppercase chr2lcase chr2ucase

Functions to convert single character on lowercase and to uppercase.
Any other character passed remain unchanged.
: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
    }
}

example code

:put [$chr2lcase "A"]

:put [$chr2ucase "a"]
Last edited by rextended on Wed Mar 15, 2023 12:16 pm, edited 1 time in total.
 
User avatar
rextended
Forum Guru
Forum Guru
Posts: 11982
Joined: Tue Feb 25, 2014 12:49 pm
Location: Italy
Contact:

Re: I did it! Script to compute UNIX time!

Wed Mar 15, 2023 12:16 pm

search tag # rextended str2case string lowercase uppercase proper case

Functions to convert a string to lowercase, uppercase or proper case (only the first letter up, the other low)
Any other non A-Z a-z character passed remain unchanged.

Optional parameter:
1) no parameter convert the first letter uppercase, all the others lowercase.
2) "U" convert to upper case
3) "L" convert to lower case
4) "P" convert to proper case: only the first letter on each word are uppercase, the remaining lower.

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

examples code

[] > :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
Last edited by rextended on Wed Mar 15, 2023 2:42 pm, edited 2 times in total.
 
User avatar
diamuxin
Member
Member
Posts: 319
Joined: Thu Sep 09, 2021 5:46 pm
Location: Alhambra's City

Re: I did it! Script to compute UNIX time!

Wed Mar 15, 2023 2:20 pm

Interesting, thank you!

I've tried it and something is wrong here:
[] > :put [$str2case "this iS a teSt ,a teSt is it"]
This is a test ,a test is it
U and L works fine.

BR.
 
User avatar
rextended
Forum Guru
Forum Guru
Posts: 11982
Joined: Tue Feb 25, 2014 12:49 pm
Location: Italy
Contact:

Re: I did it! Script to compute UNIX time!

Wed Mar 15, 2023 2:37 pm

I've tried it and something is wrong here […]
Yes, I have pasted a work in progress code, fixed the description of the parameter on the post.

I'm going to change the script to implement on no-parameter the "First only case": the Uppercase only at the start, the rest lower.
Is why you get "This is a test ,a test is it"

Also fixed examples
 
User avatar
rextended
Forum Guru
Forum Guru
Posts: 11982
Joined: Tue Feb 25, 2014 12:49 pm
Location: Italy
Contact:

Re: I did it! Script to compute UNIX time!

Wed Mar 15, 2023 2:50 pm

Also can be added "first letters uppercase after , . ; ! ? etc.",
but then it becomes too complicated for how it was thought.
Of course, to do this, a small modification is enough to check if the previous character was one of those in the list considered as sentence breaks...
but here we go further...
 
User avatar
kvee
newbie
Posts: 38
Joined: Mon Feb 13, 2023 7:59 pm

Re: I did it! Script to compute UNIX time!

Thu Apr 06, 2023 9:08 pm

This one supported full date format (example: apr/07/04 18:32:41).
:global EpochTime do={
	# Usage
	# $EpochTime [time input]
	# -----
	# Get current time
	# :put [$EpochTime]
	# 
	# Read log time in one of these two format "may/01 16:23:50" or "12:02:23" for log number *323
	# :put [$EpochTime [:log get *323 time]]

	:local ds
	:local ts
	:if ([:len $1]=0) do={
		# Get "now time"
		:set ds [/system clock get date]
		:set ts [/system clock get time]
	} else={
		if ([:len $1]=20) do={
			# Use full date format. example: "apr/22/2023 16:33:41"
			:set ds "$[:pick $1 0 6]/$[:tonum [:pick $1 7 11]]"
			:set ts [:pick $1 12 20]
		}
		if ([:len $1]>8 && [:len $1]<20) do={
			# Use remote date and time and convert date
			:set ds "$[:pick $1 0 6]/$[:pick [/system clock get date] 7 11]"
			:set ts [:pick $1 7 15]
		}
		if ([:len $1]<=8) do={
			# Use remote time and get date
			: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])
}
Thanks to @minks for the code and @jotne for update. And thank you everyone.
Last edited by kvee on Fri Apr 07, 2023 5:21 am, edited 2 times in total.
 
User avatar
rextended
Forum Guru
Forum Guru
Posts: 11982
Joined: Tue Feb 25, 2014 12:49 pm
Location: Italy
Contact:

Re: I did it! Script to compute UNIX time!

Thu Apr 06, 2023 9:28 pm

That his script doesn't work when timezone is negative, @minks do not do probably any test....

And also have some other errors, so I write my own version on previous post on this topic & related new versions on links.

For example, if you live on GMT-04:00, the script if is queried with apr/22/2023 16:33:41 reply with unexpected invalid value...
-2612771675 (Wednesday 16 March 1887 14:05:25)


For convert generic datetime to unix is already existant one working script:
viewtopic.php?p=994781#p992586

I copy that script here for simplicity
:global datetime2epoch do={
    :local dtime [:tostr $1]
    /system clock
    :local cyear [get date] ; :if ($cyear ~ "....-..-..") do={:set cyear [:pick $cyear 0 4]} else={:set cyear [:pick $cyear 7 11]}
    :if (([:len $dtime] = 10) or ([:len $dtime] = 11)) do={:set dtime "$dtime 00:00:00"}
    :if ([:len $dtime] = 15) do={:set dtime "$[:pick $dtime 0 6]/$cyear $[:pick $dtime 7 15]"}
    :if ([:len $dtime] = 14) do={:set dtime "$cyear-$[:pick $dtime 0 5] $[:pick $dtime 6 14]"}
    :if ([:len $dtime] =  8) do={:set dtime "$[get date] $dtime"}
    :if ([:tostr $1] = "") do={:set dtime ("$[get date] $[get time]")}
    :local vdate [:pick $dtime 0 [:find $dtime " " -1]]
    :local vtime [:pick $dtime ([:find $dtime " " -1] + 1) [:len $dtime]]
    :local vgmt  [get gmt-offset]; :if ($vgmt > 0x7FFFFFFF) do={:set vgmt ($vgmt - 0x100000000)}
    :if ($vgmt < 0) do={:set vgmt ($vgmt * -1)}
    :local arrm  [:toarray "0,0,31,59,90,120,151,181,212,243,273,304,334"]
    :local vdoff [:toarray "0,4,5,7,8,10"]
    :local MM    [:pick $vdate ($vdoff->2) ($vdoff->3)]
    :local M     [:tonum $MM]
    :if ($vdate ~ ".../../....") do={
        :set vdoff [:toarray "7,11,1,3,4,6"]
        :set M     ([:find "xxanebarprayunulugepctovecANEBARPRAYUNULUGEPCTOVEC" [:pick $vdate ($vdoff->2) ($vdoff->3)] -1] / 2)
        :if ($M>12) do={:set M ($M - 12)}
    }
    :local yyyy  [:pick $vdate ($vdoff->0) ($vdoff->1)] ; :if ((($yyyy - 1968) % 4) = 0) do={:set ($arrm->1) -1; :set ($arrm->2) 30}
    :local totd  ((($yyyy - 1970) * 365) + (($yyyy - 1968) / 4) + ($arrm->$M) + ([:pick $vdate ($vdoff->4) ($vdoff->5)] - 1))
    :return      (((((($totd * 24) + [:pick $vtime 0 2]) * 60) + [:pick $vtime 3 5]) * 60) + [:pick $vtime 6 8] - $vgmt)
}

example code

# example on GMT-04:00
[] > :put [$datetime2epoch "apr/22/2023 16:33:41"]
1682166821

# example on GMT+02:00
[] > :put [$datetime2epoch "apr/22/2023 16:33:41"]
1682174021

# example on GMT+02:00 withour year, like scheduler next run and log
[] > :put [$datetime2epoch "apr/22 16:33:41"] (is supposed 2023 from local clock)
1682174021

# work also with 1st letter uppercase or all uppercase
[] > :put [$datetime2epoch "Apr/22 16:33:41"] (is supposed 2023 from local clock)
1682174021

# work also with new RouterOS v7.10+ ISO formats
[] > :put [$datetime2epoch "2023-04-22 16:33:41"]
1682174021
[] > :put [$datetime2epoch "04-22 16:33:41"] (is supposed 2023 from local clock)
1682174021

# work also with only time, like on logs
[] > :put [$datetime2epoch "16:33:41"] (is supposed apr/22/2023 from local clock)
1682174021

# example for "now" (on GMT+02:00)
[] > :put [$datetime2epoch]
1680806933
Last edited by rextended on Fri May 19, 2023 3:17 pm, edited 10 times in total.
 
User avatar
diamuxin
Member
Member
Posts: 319
Joined: Thu Sep 09, 2021 5:46 pm
Location: Alhambra's City

Re: I did it! Script to compute UNIX time!

Sat Apr 08, 2023 3:24 pm

Awesome, as always rextended to the rescue!
:wink:
 
User avatar
rextended
Forum Guru
Forum Guru
Posts: 11982
Joined: Tue Feb 25, 2014 12:49 pm
Location: Italy
Contact:

Re: I did it! Script to compute UNIX time!

Fri May 19, 2023 1:26 pm

Awesome, as always rextended to the rescue!
:wink:
Thanks, I forget no time log if is exactly at 00:00:00 ;)

Fixed
 
User avatar
diamuxin
Member
Member
Posts: 319
Joined: Thu Sep 09, 2021 5:46 pm
Location: Alhambra's City

Re: I did it! Script to compute UNIX time!

Fri Oct 06, 2023 8:08 pm

Hi Rex !

For your super-function "datetime2epoch" how could we adapt the following date?

2023-Aug-31 16:55

It is to extract the date from a changelog that comes with a somewhat peculiar format (Mikrotik has not yet unified the dates to ISO 8601).

changelog code

What's new in 7.11.2 (2023-Aug-31 16:55):

*) dhcp - fixed DHCP server "authoritative" and "delay-threshold" settings (introduced in v7.11.1);

Thanks in advance!
 
User avatar
diamuxin
Member
Member
Posts: 319
Joined: Thu Sep 09, 2021 5:46 pm
Location: Alhambra's City

Re: I did it! Script to compute UNIX time!

Fri Oct 06, 2023 10:07 pm

I think I have found the solution, before the next local variable in the code of @rextended
viewtopic.php?p=1029048#p994849

:local yyyy [:pick $vdate ($vdoff->0) ($vdoff->1)] ; :if (((($yyyyy - 1968) % 4) = 0) do={:set ($arrm->1) -1; :set ($arrm->2) 30}

Add this code snippet

 
    :if ($vdate ~ "....-...-..") do={
        :set vdoff [:toarray "0,4,6,8,9,11"]
        :set M     ([:find "xxanebarprayunulugepctovecANEBARPRAYUNULUGEPCTOVEC" [:pick $vdate ($vdoff->2) ($vdoff->3)] -1] / 2)
        :if ($M>12) do={:set M ($M - 12)}
    }
 

Test:
:put [$unixtodatetime [$datetime2epoch "2023-Aug-31 16:55"]]
output:  2023/08/31 16:55:00
 
texmeshtexas
Member Candidate
Member Candidate
Posts: 151
Joined: Sat Oct 11, 2008 11:17 pm

Re: I did it! Script to compute UNIX time!

Wed Oct 11, 2023 2:07 am

That his script doesn't work when timezone is negative, @minks do not do probably any test....

And also have some other errors, so I write my own version on previous post on this topic & related new versions on links.

For example, if you live on GMT-04:00, the script if is queried with apr/22/2023 16:33:41 reply with unexpected invalid value...
-2612771675 (Wednesday 16 March 1887 14:05:25)


For convert generic datetime to unix is already existant one working script:
viewtopic.php?p=994781#p992586

I copy that script here for simplicity
:global datetime2epoch do={
    :local dtime [:tostr $1]
    /system clock
    :local cyear [get date] ; :if ($cyear ~ "....-..-..") do={:set cyear [:pick $cyear 0 4]} else={:set cyear [:pick $cyear 7 11]}
    :if (([:len $dtime] = 10) or ([:len $dtime] = 11)) do={:set dtime "$dtime 00:00:00"}
    :if ([:len $dtime] = 15) do={:set dtime "$[:pick $dtime 0 6]/$cyear $[:pick $dtime 7 15]"}
    :if ([:len $dtime] = 14) do={:set dtime "$cyear-$[:pick $dtime 0 5] $[:pick $dtime 6 14]"}
    :if ([:len $dtime] =  8) do={:set dtime "$[get date] $dtime"}
    :if ([:tostr $1] = "") do={:set dtime ("$[get date] $[get time]")}
    :local vdate [:pick $dtime 0 [:find $dtime " " -1]]
    :local vtime [:pick $dtime ([:find $dtime " " -1] + 1) [:len $dtime]]
    :local vgmt  [get gmt-offset]; :if ($vgmt > 0x7FFFFFFF) do={:set vgmt ($vgmt - 0x100000000)}
    :if ($vgmt < 0) do={:set vgmt ($vgmt * -1)}
    :local arrm  [:toarray "0,0,31,59,90,120,151,181,212,243,273,304,334"]
    :local vdoff [:toarray "0,4,5,7,8,10"]
    :local MM    [:pick $vdate ($vdoff->2) ($vdoff->3)]
    :local M     [:tonum $MM]
    :if ($vdate ~ ".../../....") do={
        :set vdoff [:toarray "7,11,1,3,4,6"]
        :set M     ([:find "xxanebarprayunulugepctovecANEBARPRAYUNULUGEPCTOVEC" [:pick $vdate ($vdoff->2) ($vdoff->3)] -1] / 2)
        :if ($M>12) do={:set M ($M - 12)}
    }
    :local yyyy  [:pick $vdate ($vdoff->0) ($vdoff->1)] ; :if ((($yyyy - 1968) % 4) = 0) do={:set ($arrm->1) -1; :set ($arrm->2) 30}
    :local totd  ((($yyyy - 1970) * 365) + (($yyyy - 1968) / 4) + ($arrm->$M) + ([:pick $vdate ($vdoff->4) ($vdoff->5)] - 1))
    :return      (((((($totd * 24) + [:pick $vtime 0 2]) * 60) + [:pick $vtime 3 5]) * 60) + [:pick $vtime 6 8] - $vgmt)
}

example code

# example on GMT-04:00
[] > :put [$datetime2epoch "apr/22/2023 16:33:41"]
1682166821

# example on GMT+02:00
[] > :put [$datetime2epoch "apr/22/2023 16:33:41"]
1682174021

# example on GMT+02:00 withour year, like scheduler next run and log
[] > :put [$datetime2epoch "apr/22 16:33:41"] (is supposed 2023 from local clock)
1682174021

# work also with 1st letter uppercase or all uppercase
[] > :put [$datetime2epoch "Apr/22 16:33:41"] (is supposed 2023 from local clock)
1682174021

# work also with new RouterOS v7.10+ ISO formats
[] > :put [$datetime2epoch "2023-04-22 16:33:41"]
1682174021
[] > :put [$datetime2epoch "04-22 16:33:41"] (is supposed 2023 from local clock)
1682174021

# work also with only time, like on logs
[] > :put [$datetime2epoch "16:33:41"] (is supposed apr/22/2023 from local clock)
1682174021

# example for "now" (on GMT+02:00)
[] > :put [$datetime2epoch]
1680806933
Something is not right. I'm trying to calculate the number of days between two dates.
dateEx=2023-Aug-31 16:55 (release date from change log on http://upgrade.mikrotik.com/routeros/<v ... /CHANGELOG
currDate=2023-10-10 current date on router

:local EPOCHdateEx [$datetime2epoch $dateEx]
:local EPOCHcurrDate [$datetime2epoch $currDate]

:log info "EPOCH of currDate=$EPOCHcurrDate"
:log info "EPOCH of DateEx=$EPOCHdateEx"

:global DSR
:set DSR (($EPOCHcurrDate - $EPOCHdateEx)/86400)
:log info "Days since release=$DSR"

EPOCH of currDate=1696878000
EPOCH of DateEx=1672228500

This results in DSR of 285
however the time between Aug 31 and Oct 10 is is about 40 days, not 285 days
 
texmeshtexas
Member Candidate
Member Candidate
Posts: 151
Joined: Sat Oct 11, 2008 11:17 pm

Re: I did it! Script to compute UNIX time!

Wed Oct 11, 2023 4:55 pm

I think I figured this out
script does not like this date format that comes from MT changelog
2023-Aug-31 16:55

:put [$datetime2epoch "2023-Aug-31 16:55"]
1672228500

:put [$datetime2epoch "2023-08-31 16:55"]
1693482900
 
User avatar
diamuxin
Member
Member
Posts: 319
Joined: Thu Sep 09, 2021 5:46 pm
Location: Alhambra's City

Re: I did it! Script to compute UNIX time!

Wed Oct 11, 2023 5:44 pm

Operations code

:local A [$datetime2epoch "2023-09-30 16:55"]
1696085700

:local B [$datetime2epoch "2023-08-31 16:55"]
1693493700

Result:
A - B / 86400 = 30 days

Note: The converter to change the Changelog date to the MT date can be found at:
viewtopic.php?t=200103#p1029782

Good luck!
 
error404
just joined
Posts: 10
Joined: Sat Oct 21, 2023 1:58 pm

Re: I did it! Script to compute UNIX time!

Tue Nov 14, 2023 6:19 pm

Since ROS 7.12 it is much easier to get a unix time.
:local currentTime [:pick [:tonsec [:timestamp]] 0 10];
:log info "$currentTime";

Output:
1699977978

It gives you GMT+0000 time, so you still need some manipulations to adjust it to your time zone.
Hope it would be helpful.
 
User avatar
rextended
Forum Guru
Forum Guru
Posts: 11982
Joined: Tue Feb 25, 2014 12:49 pm
Location: Italy
Contact:

Re: I did it! Script to compute UNIX time!

Tue Nov 14, 2023 7:31 pm

Why all that?

Suffice just
:put  [:tonum [:timestamp]]
 
User avatar
gwindalmir
just joined
Posts: 1
Joined: Fri Jun 23, 2023 9:54 am

Re: I did it! Script to compute UNIX time!

Sun Dec 03, 2023 10:34 am

That his script doesn't work when timezone is negative, @minks do not do probably any test....

And also have some other errors, so I write my own version on previous post on this topic & related new versions on links.

For example, if you live on GMT-04:00, the script if is queried with apr/22/2023 16:33:41 reply with unexpected invalid value...
-2612771675 (Wednesday 16 March 1887 14:05:25)


For convert generic datetime to unix is already existant one working script:
viewtopic.php?p=994781#p992586

I copy that script here for simplicity
:global datetime2epoch do={
    :local dtime [:tostr $1]
    /system clock
    :local cyear [get date] ; :if ($cyear ~ "....-..-..") do={:set cyear [:pick $cyear 0 4]} else={:set cyear [:pick $cyear 7 11]}
    :if (([:len $dtime] = 10) or ([:len $dtime] = 11)) do={:set dtime "$dtime 00:00:00"}
    :if ([:len $dtime] = 15) do={:set dtime "$[:pick $dtime 0 6]/$cyear $[:pick $dtime 7 15]"}
    :if ([:len $dtime] = 14) do={:set dtime "$cyear-$[:pick $dtime 0 5] $[:pick $dtime 6 14]"}
    :if ([:len $dtime] =  8) do={:set dtime "$[get date] $dtime"}
    :if ([:tostr $1] = "") do={:set dtime ("$[get date] $[get time]")}
    :local vdate [:pick $dtime 0 [:find $dtime " " -1]]
    :local vtime [:pick $dtime ([:find $dtime " " -1] + 1) [:len $dtime]]
    :local vgmt  [get gmt-offset]; :if ($vgmt > 0x7FFFFFFF) do={:set vgmt ($vgmt - 0x100000000)}
    :if ($vgmt < 0) do={:set vgmt ($vgmt * -1)}
    :local arrm  [:toarray "0,0,31,59,90,120,151,181,212,243,273,304,334"]
    :local vdoff [:toarray "0,4,5,7,8,10"]
    :local MM    [:pick $vdate ($vdoff->2) ($vdoff->3)]
    :local M     [:tonum $MM]
    :if ($vdate ~ ".../../....") do={
        :set vdoff [:toarray "7,11,1,3,4,6"]
        :set M     ([:find "xxanebarprayunulugepctovecANEBARPRAYUNULUGEPCTOVEC" [:pick $vdate ($vdoff->2) ($vdoff->3)] -1] / 2)
        :if ($M>12) do={:set M ($M - 12)}
    }
    :local yyyy  [:pick $vdate ($vdoff->0) ($vdoff->1)] ; :if ((($yyyy - 1968) % 4) = 0) do={:set ($arrm->1) -1; :set ($arrm->2) 30}
    :local totd  ((($yyyy - 1970) * 365) + (($yyyy - 1968) / 4) + ($arrm->$M) + ([:pick $vdate ($vdoff->4) ($vdoff->5)] - 1))
    :return      (((((($totd * 24) + [:pick $vtime 0 2]) * 60) + [:pick $vtime 3 5]) * 60) + [:pick $vtime 6 8] - $vgmt)
}
Ironically, your script doesn't work if the input time is in local time, and the timezone is negative either. :D

I had to remove this line for it to work:
:if ($vgmt < 0) do={:set vgmt ($vgmt * -1)}
Here's an example of the problem I encountered:
[admin@MikroTik] > /file/print where name~"tmp/"                                                            
Columns: NAME, TYPE, SIZE, CREATION-TIME
 #  NAME                                       TYPE       SIZE     CREATION-TIME      
 1  tmp/porch-1701563598.650905-4y9fhm.jpg     .jpg file  56.7KiB  2023-12-02 16:33:22
47  tmp/porch-1701564732.657804-0a4suc.jpg     .jpg file  54.8KiB  2023-12-02 16:52:14
48  tmp/porch-1701564736.036827-7835rl.jpg     .jpg file  66.2KiB  2023-12-02 16:52:18
49  tmp/porch-1701564793.43657-iih2aj.jpg      .jpg file  73.3KiB  2023-12-02 16:53:30
50  tmp/porch-1701565635.980733-g4u624.jpg     .jpg file  54.7KiB  2023-12-02 23:31:50
 2  tmp/driveway-1701512263.230008-pg6q5n.jpg  .jpg file  40.3KiB  2023-12-02 03:27:12
 3  tmp/driveway-1701512256.183251-zno65t.jpg  .jpg file  42.3KiB  2023-12-02 03:27:12
 4  tmp/porch-1701512256.171489-20z0ld.jpg     .jpg file  42.8KiB  2023-12-02 03:36:22
[admin@MikroTik] > :put [$datetime2epoch [/file/get "tmp/porch-1701565635.980733-g4u624.jpg" creation-time]]
1701531110
[admin@MikroTik] > /system/clock/print                                                                      
                  time: 00:32:29
                  date: 2023-12-03
  time-zone-autodetect: no
        time-zone-name: America/Los_Angeles
            gmt-offset: -08:00
            dst-active: no
[admin@MikroTik] > 
1701531110 is Saturday, December 2, 2023 3:31:50 PM GMT, which is wrong (my timezone is GMT-8). The proper epoch value I expected was 1701588710, which the modification I made outputs correctly.

Thanks for the script regardless, it saved me a lot of time!

Who is online

Users browsing this forum: No registered users and 23 guests