Calculate date and time in script

Hello everyone,

I’m trying to calculate an end date with 2 variables:

1 the initial value ($lastSeenStr) which has the format MM/DD/YYYY HH/MM/SS example: mar/04/2024 16:37:18.

and the other variable ($validity) which can have 2 formats: 3d00:00:00 or 01:00:00

I would like to find the end date by adding the variable $lastSeenStr + $validity = $Endvaliditydatetime


Thank you for your help

See script in this post, for converting $lastSeenStr (date-time format) into timestamp you can use $datetime2epoch function created by @rextended taken from here, $validity is in time type, to convert it into timestamp you can use ROS global command :tonum, in your case [:tonum $validity] (if is string variable you can convert it with [:tonum [:totime $validity]]) and then you can sum both timestamps. If you need to convert summed timestamps result back to date-time format you can use also @rextended function $unixtodatetime from here.

hello and thank you for your feedback


the first variable is ok but I have a problem with $validity, I can’t retrieve a value.

as this value can have the format: 3d00:00:00 or 01:00:00 I would like to have it in the same type of result as the datetime2epoch function in order to calculate it with

thank you again for your help

Regarding $validity it is already explained in my previous post, but if is hard to understand, here it is:

>:local validity 3d00:00:00; :put [:tonum $validity]
259200
>:local validity 01:00:00; :put [:tonum $validity]
3600
>:local validity "3d00:00:00"; :put [:tonum [:totime $validity]]
259200
>:local validity "01:00:00"; :put [:tonum [:totime $validity]]
3600

1ft + 1m do not do 2_something_,

You must first convert ft to m, or m to ft, or both to another omogeneous format.

Since “mar/04/2024 16:37:18” is a stupid string, only an idiot of a programmer (I’m referring to the past) could choose such
a silly method of representing the date, instead of using a better sortable and more matematically logic form, like: 2024-03-04 16:37:18.
(same consideration for the Italian “& Co.” 04/03/2024),

Since a string is a string, you must first convert date-time to unix time and interval to seconds, then this is possible:
current_unix_time + time_interval_seconds = next_unix_time

Converting next_unix_time back to one date, you have the wanted value.


For example this print current timestamp value ahead of 1 hour on v7.13.5

:put ([:timestamp] + 1h)

the same, but for out the unix epoch, but this time 3 days

:put [:tonum ([:timestamp] + 3d)]

The function datetime2epoch is explained here
http://forum.mikrotik.com/t/i-did-it-script-to-compute-unix-time/68576/24

And unixtodatetime here
http://forum.mikrotik.com/t/convert-uptime-to-date-and-time/157724/36

hello and thank you for your feedback, I am trying to integrate it into my script with this code:

        :local validitytime [:tonum $validity];
        :log info "validitytime: $validitytime";

but nothing appears in my logs:

Thank you for your help
Capture d'écran 2024-03-06 095943.png

Is it $validity string type variable then? Did you try

:local validitytime [:tonum [:totime $validity]]
:log info "validitytime: $validitytime"

?
Or could be ROS version issue, you did not specify on which is this performed, maybe on older versions :tonum from time doesn’t work.

here is my current version:
Capture d'écran 2024-03-06 104531.png
and yes I tried:

 
        :local validitytime [:tonum [:totime $validity]];
        :log info "validitytime: $validitytime";

and that doesn’t work either

the variable $validity comes from the following code:

        :local validity [/tool user-manager profile limitation get $profileLimit value-name=uptime-limit];
        :log info "validity: $validity";

on v6.x do not work any that is only on v7.x

you can use only my functions on v6


Example of 3 days (259200 seconds) and 1 hour (3600 seconds) ahead mar/04/2024 16:37:18
: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)
}

:global unixtodatetime 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)}
:if ($vgmt < 0) do={: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)])
:return “$yearStart/$[$Fzerofill $mnthStart]/$[$Fzerofill $dayStart] $timeStart”
}

:put [$unixtodatetime ([$datetime2epoch “mar/04/2024 16:37:18”] + 259200)]

:put [$unixtodatetime ([$datetime2epoch “mar/04/2024 16:37:18”] + 3600)]