Script function for converting and shifting the standard date to OS MikroTik
Start variables:
First mandatory variable in “aug/22/2021” or “08/22/2021” format.
Second optional variable in -5 or 0 or 5 format. Specifies how many days forward or backward you want to move the total date as a result.
Third optional variable in true or false format. The value of the “true” variable prevents you from changing the format of the month from text to number and from number to text.
:global FuncDateConvert do={
:local LocalDate $1
:local ChangeDay $2
:local NoConvertMonth $3
:local Day [:pick $LocalDate ([:find $LocalDate "/" -1] + 1) [:find $LocalDate "/" [:find $LocalDate "/" -1]]]
:local Month [:pick $LocalDate -1 [:find $LocalDate "/" -1]]
:local Year [:pick $LocalDate ([:find $LocalDate "/" [:find $LocalDate "/" -1]] + 1) [:len $LocalDate]]
:local ArrayMonth {"jan";"feb";"mar";"apr";"may";"jun";"jul";"aug";"sep";"oct";"nov";"dec"}
:local ArrayMonthDay {31;28;31;30;31;30;31;31;30;31;30;31}
:local MonthType "str"
# Check the input format and correct if necessary.
:if ( [:typeof $NoConvertMonth] = "nothing") do={:set $NoConvertMonth "false"}
:if ( [:typeof $ChangeDay] = "nothing") do={:set $ChangeDay 0}
:if ( [:typeof $ChangeDay] = "str") do={:set $ChangeDay [:tonum $ChangeDay]}
:if ( [:typeof $Day] = "str") do={:set $Day [:tonum $Day]}
:if ( [:typeof $Year] = "str") do={:set $Year [:tonum $Year]}
# Check the data format of the Month variable and correct if necessary.
:if ( $Month~"^[0-9]{1,2}\$") do={
:set $Month [:tonum $Month]
:set $MonthType "num"
}
# Calculate the numerical equivalent for the Month variable
:if ($MonthType = "str") do={
:foreach MonthNum,MonthStr in=$ArrayMonth do={
:if ($MonthStr = $Month) do={:set $Month ($MonthNum + 1)}
}
}
# Calculate date shift by specified number of days
:if ($ChangeDay > 0) do={
:set $Day ($Day + $ChangeDay)
:while ((($Day > ($ArrayMonthDay->($Month - 1))) and ((($Year % 4) != 0) or ((($Year % 4) = 0) and ($Month != 2)))) or \
(($Day > (($ArrayMonthDay->($Month - 1)) + 1)) and ($Month = 2) and (($Year % 4) = 0))) do={
:if (($Month = 2) and (($Year % 4) = 0)) do={:set $Day ($Day - (($ArrayMonthDay->($Month - 1)) + 1))
} else={:set $Day ($Day - ($ArrayMonthDay->($Month - 1)))}
:set $Month ($Month + 1)
:if ($Month > 12) do={:set $Year ($Year + 1); :set $Month 1}
}
}
:if ($ChangeDay < 0) do={
:set $Day ($Day + $ChangeDay )
:while ($Day < 1) do={
:set $Month ($Month - 1)
:if ($Month < 1) do={:set $Year ($Year - 1); :set $Month 12}
:if (($Month = 2) and (($Year % 4) = 0)) do={:set $Day ($Day + (($ArrayMonthDay->($Month - 1)) + 1))
} else={:set $Day ($Day + ($ArrayMonthDay->($Month - 1)))}
}
}
# Add the character 0 to the beginning of the Day variable
:if (($Day < 10) and ([:len $Day] < 2)) do={:set $Day ("0".$Day)}
# Calculate the text equivalent for the Month variable
:if (($MonthType = "num") and ($NoConvertMonth = "false")) do={:set $Month ($ArrayMonth->($Month - 1))}
# Add the character 0 to the beginning of the Month variable
:if (($MonthType = "num") and ($NoConvertMonth = "true") and ($Month < 10)) do={:set $Month ("0".$Month)}
# Calculate the text equivalent for the Month variable
:if (($MonthType = "str") and ($NoConvertMonth = "true")) do={:set $Month ($ArrayMonth->($Month - 1))}
# Add the character 0 to the beginning of the Month variable
:if (($MonthType = "str") and ($NoConvertMonth = "false") and ($Month < 10)) do={:set $Month ("0".$Month)}
# Return data array in MM/DD/YYYY, DD, MM, YYYY format
:return {($Month."/".$Day."/".$Year);$Day;$Month;$Year}
}
Calculation of a high year, when in February + 1 day did not realize due to the lack of technical work with fractions. This is an error in operation.
If you have a technical solution, please describe it.
Fixed error with date reduction:
:put ([$FuncDateConvert “jan/01/2024” -10]->0)
12/22/2023
:put ([$FuncDateConvert “jan/01/2024” -25]->0)
12/07/2023
Fixed the return value of the Day variable if it is less than 10. Appends 0 before the number.
Why use fraction?
ignoring century and other complex rules for feb 29 (if we are alive on 2100 we fix that),
simpy 2021 % 4 = 1 … only if reminder is 0 the year have feb 29 day
Good afternoon.
Do you propose to change the date output and execute it in ISO format?
You can generate a date in any format from the output array of the function.
My goal with this feature is to convert an array that contains the dates when the files were created. In the future, sort by ascending based on the Date field and delete obsolete files.
There is a script that generates backup files in the "backup" + "rsc" formats and sends to mail.
It is. There is a need to clean the MikroTik OS file system according to certain criteria.
Developers of MikroTik OS did not take care of the functionality of converting and comparing this in the format "Date."
On the previous question:
Do you suggest accepting a date in a different format for processing?
Do you suggest displaying in a different format?
Do you want to add an incoming parameter to correctly read the date in the ISO8601 format?
As for the date the files were created, thank you for specifying. In my case, it's not a problem. Files are created on a schedule and are not modified. So for a particular set of files, I can rotate files.
I think if you have already the date on ISO8601 like 20210823 format on filename, is useless check time.
For example, if you do backup every week (but is better to do not leave inside but do it by mail or on another device)
on the script delete the file than have inside two month ago.
Honestly, I'll tell you.
I had no desire to forge file names. Process the creation and modification date of the object faster than extracting the date from the file name. And I want a kind of universality.
That's what you think. Files are sent to email mail. And here there is a desire to organize file rotation.
:local month <from your function actual month - 2>
:local id [/system identity get name]
/file remove [find where name~“^$id-[0-9]{4}$month[0-9]{2}-[0-9]{4}\.(backup|rsc)$”]
Once you set 1st time the directory clean, automatically delete 3 monts old backup
A good and simple solution that I discarded because all files will be deleted for the specified month. You can stay with one single backup file in the new month. Of course there are backup files in the mail.
In my opinion, the best solution will be to compare the entire date without time.
Your example of deleting files simplified what I wanted to do. Thank you.
I am very happy every time someone shares something new.
I saw some interesting potential from your script,
otherwise I would not have tried to suggest things to you,
and certainly in the future you will come up with a solution to something else,
thanks to what you made me think today.
Really thanks for that.
Another hint, regexp matching 1 to 12 and 01 to 09:
^([0]?[1-9]|1[0-2])\$
matches
if there is present 0 or not followed by a number from 1 to 9
OR
by a 1 followed by a number from 0 to 2
Remember to add \ before ? on terminal, on script do not put the \ before ?
The only things I have to say now, is: please format the script or is hard to understand