cron-utils icon indicating copy to clipboard operation
cron-utils copied to clipboard

Migrate cron expression to another timezone

Open jmrozanec opened this issue 7 years ago • 37 comments

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

jmrozanec avatar Oct 05 '17 13:10 jmrozanec

The same use case is reported at Stackoverflow

jmrozanec avatar Nov 11 '17 14:11 jmrozanec

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 avatar Nov 19 '17 13:11 SvenssonWeb

@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.

jmrozanec avatar Nov 20 '17 13:11 jmrozanec

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 avatar Sep 10 '18 09:09 benjwarner

@benjwarner thank you for the example provided! We will prioritize this issue for next release. You are also welcome to contribute :smile: Thanks!

jmrozanec avatar Sep 10 '18 13:09 jmrozanec

@jmrozanec Is this issue already taken? If not then i wish to work on it.

antrix190 avatar Oct 19 '18 23:10 antrix190

@antrix190 work in it! We will be glad to merge your PR! Thanks! :smile:

jmrozanec avatar Oct 20 '18 04:10 jmrozanec

Sure!

antrix190 avatar Oct 20 '18 08:10 antrix190

@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.

jmrozanec avatar Oct 22 '18 19:10 jmrozanec

Hey @jmrozanec I need sometime to close this issue.

antrix190 avatar Oct 28 '18 00:10 antrix190

@antrix190 sure! Seems easy, but has lots of corner cases :) thanks!

jmrozanec avatar Oct 28 '18 05:10 jmrozanec

@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! 😄

jmrozanec avatar Oct 28 '18 12:10 jmrozanec

So what is the current status of this task?

HerTesla avatar Mar 12 '19 12:03 HerTesla

@HerTesla you can take this up.

antrix190 avatar Mar 12 '19 14:03 antrix190

@antrix190 perhaps do we have some code that can be reused? @HerTesla you are welcome to help with this!

jmrozanec avatar Mar 12 '19 15:03 jmrozanec

can i pick this..?

fahmpeermoh avatar Oct 19 '19 10:10 fahmpeermoh

@fahmpeermoh sure! Will be happy to merge!

jmrozanec avatar Oct 19 '19 10:10 jmrozanec

@jmrozanec Thank you.

fahmpeermoh avatar Oct 21 '19 05:10 fahmpeermoh

Thank you guys for following up this feature :)

jrphub avatar Nov 16 '19 04:11 jrphub

@fahmpeermoh any news on this?

jmrozanec avatar Nov 16 '19 07:11 jmrozanec

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.

aleskiontherun avatar Dec 13 '19 08:12 aleskiontherun

@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 avatar Dec 14 '19 18:12 jmrozanec

@jmrozanec I'm talking about the tests in the pull request ;) https://github.com/jmrozanec/cron-utils/pull/400/files#diff-191b64506d58f9422b0b28100abfed44

aleskiontherun avatar Dec 16 '19 10:12 aleskiontherun

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?

dswitzer avatar Feb 27 '20 17:02 dswitzer

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.

dswitzer avatar Feb 27 '20 17:02 dswitzer

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```

Gwynbleidd017 avatar Mar 24 '20 00:03 Gwynbleidd017

@jarvis017 this script is helpful! We will try to translate ASAP into our code. Meanwhile, you are welcome to contribute as well! Thanks!

jmrozanec avatar Mar 24 '20 15:03 jmrozanec

has this feature been added to cron-utils ?? or is it still open

kakumasn avatar Aug 12 '20 13:08 kakumasn

@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.

jmrozanec avatar Aug 13 '20 05:08 jmrozanec

Hi Any updates on this

saurabnigam avatar Sep 04 '20 20:09 saurabnigam