cron-utils
cron-utils copied to clipboard
Migrate cron expression to another timezone
I need something like below:
newCronExpression = convert (localCronExpresn,fromLocalTZ, "UTC")
Is it possible using cron-utils?
Let me give an example:
My local timezone is IST i.e. GMT+5.30.
Current local time is: 11:20 AM.
I want a job to run in 45 min of every hour.
So, my cron expression: 45 * * * *
Hence I am expecting my job to run after 25 min ( as starting time is 11:45 AM)
but my job is running as per UTC, because of oozie.
Current time in UTC : 05:50 AM
As per cron expression 45 * * * , the starting time will be 06:45 AM at GMT.
So, the job will be actually started after 55 min.
Expected : After 25 min
Actual : After 55 min
So,
if I am converting my local cron expression 45 ** * * to 15 * * * * at GMT, then actual waiting period will be same as expected.
This feature was originally reported at cron-utils-examples by @jrphub
The same use case is reported at Stackoverflow
Is this really supposed to be a part of this utility? Doing the timezone conversion before building the cron expression would probably be easier for everyone. I could see the use case for this if you are writing the cron expression by hand and plugging it into a service. But is that really how this should be done? Adding cron expression to be run on server side, should be expected to run on server time, And if you build some UI to craft the schedules, you could do the time conversion before inserting the values into cron.
@SvenssonWeb there may be different ways to do this - we agree on that. Nevertheless, this use case may not be that straightforward: we may have cases where converting a cron expression to another timezone involve day changes, DST, etc. We understand this could be valuable for anyone who has servers in multiple time zones and needs to execute tasks at the same time, providing a single cron expression and without a central scheduler. Tweaking multiple cron expressions for different timezones would be tedious and error prone: if the library can provide this, we may save some work and headaches to someone.
A real life example that I am looking at now.
All of our servers globally run in their respective local time-zones. For various reasons, all our java apps run in UTC.
We have a single app that needs to trigger tasks at various market times. e.g. The New York Close is at 17:00 NY time. The New Zealand Open is at 8am Wellington time, etc. We also need the ability to configure these tasks to run periodically (mostly for testing purposes). So a cron sort of suits, as it can handle both.
So yes, we could look for specific times in the cron expression, and adjust them according to their Time Zone difference, but as OP suggested this would be cumbersome.
Would be awesome if we could just pass the Cron through and TZ's be taken care of.
@benjwarner thank you for the example provided! We will prioritize this issue for next release. You are also welcome to contribute :smile: Thanks!
@jmrozanec Is this issue already taken? If not then i wish to work on it.
@antrix190 work in it! We will be glad to merge your PR! Thanks! :smile:
Sure!
@antrix190 any news on this issue? It would be great to close October with a new release including this feature :smile: May seem as trivial as to replace current cron values with the GMT offset of the target timezone, but may become tricky when a block of hours gets split into two dates or similar cases. I would try mapping a single expression into equivalent ones and perhaps deliver a multi-cron that would be equivalent to the original expression. If the multi-cron can be simplified, then we should do it.
Hey @jmrozanec I need sometime to close this issue.
@antrix190 sure! Seems easy, but has lots of corner cases :) thanks!
@antrix190 if you need some help, do not hesitate to reach out on this thread and share code from your fork. Will be glad to provide assistance! 😄
So what is the current status of this task?
@HerTesla you can take this up.
@antrix190 perhaps do we have some code that can be reused? @HerTesla you are welcome to help with this!
can i pick this..?
@fahmpeermoh sure! Will be happy to merge!
@jmrozanec Thank you.
Thank you guys for following up this feature :)
@fahmpeermoh any news on this?
The merged code doesn't work with multiple values in one field, e. g. 0 9,15,18 * * *
. Also some tests do not pass due to daylight saving time offsets.
In our case we have some auto-generated Jenkins jobs, performing scheduled tasks, which need to be adjusted to daylight saving time in some time zones.
@dizeee thank you for reporting this. May we ask you to point us the tests failing due to daylight savings in some timezones? This way we can fix them. If those are tests of your own, we would welcome them into our codebase, to ensure better quality. Thanks! 😄
@jmrozanec I'm talking about the tests in the pull request ;) https://github.com/jmrozanec/cron-utils/pull/400/files#diff-191b64506d58f9422b0b28100abfed44
First, thanks for the wonderful project!
I'm working on a web-based project that uses Quartz Scheduler. The servers and the web application all run in UTC. However, clients will need to see the cron schedule expression reflected in their time zone.
The new CronConverter() code seemed to be exactly what I needed. However, as @dizeee mentioned, some of the use cases do not work as expected. For example, I would expect the following code:
cronConverter
.using("0 0/5 15-22 * * ?")
.from(ZoneId.of("UTC"))
.to(ZoneId.of("America/New_York"))
.convert()
;
To produce the string:
0 0/5 10-17 * * ?
However, the returned string is the same as the input.
Is this something that's intended to work as I expect or am I misunderstanding the intentions?
Likewise, I'd expect:
cronConverter
.using("0 0 17 * * ?")
.from(ZoneId.of("UTC"))
.to(ZoneId.of("America/New_York"))
.convert()
;
To generate:
0 0 12 * * ?
But it's generating:
0 19 16 * * ?
Which is really wrong.
Would this script help?
#!/usr/bin/python
import sys
difference_source_utc = 10
mode = sys.argv[1]
minute = sys.argv[2]
hour = sys.argv[3]
days = sys.argv[-1].split(",")
days = map(int,days);
day_change = False
if(mode == "source-utc"):
hour_result = int(hour) - difference_source_utc
if(mode == "utc-source"):
hour_result = int(hour) + difference_source_utc
if(hour_result < 0):
hour_result = hour_result + 24
days_result = [(x-1)%7 for x in days]
elif(hour_result >= 24):
hour_result = hour_result - 24
days_result = [(x+1)%7 for x in days]
else:
days_result = days
days_result_str = ','.join(map(str, days_result))
print minute , hour_result , "* *" , days_result_str
NOTE: Update difference_source_utc in the script to difference between your source and UTC. Example : For AEST it is 10.
Example 1:
Convert a local time to UTC.
./crontab-converter.py source-utc 30 08 * * 0,1,2
Result: 30 22 * * 6,0,1
Example 2:
Convert a UTC time to local.
./crontab-converter.py utc-source 30 22 * * 6,0,1
Result: 30 8 * * 0,1,2```
@jarvis017 this script is helpful! We will try to translate ASAP into our code. Meanwhile, you are welcome to contribute as well! Thanks!
has this feature been added to cron-utils ?? or is it still open
@kakumasn this feature was not added to cron-utils yet. Will do our best to include and test over next week. Will post an update when done and released.
Hi Any updates on this