Java Quartz-Scheduler via TimeZone

My server works in the time zone of Europe / Rome - and this is the default tz on the server, I need to schedule tasks according to the time zone of the user, so if a user living in the Pacific / Honolulu time zone paints a CronTrigger that shoots every day at 22:00 for his region of the Earth. I found this solution:

CronTrigger trigger = newTrigger() .withIdentity("name", "group") .withSchedule( cronSchedule("0 0 22 ? * *").inTimeZone(TimeZone.getTimeZone("Pacific/Honolulu")) ) .startNow() .build(); 

On my server, this task starts at 09:00 in the morning of "mine" the next day .

Are there any special issues that need to be considered, in addition to updating the time zone (i.e. the Time Zone Update Tool )?

If I want to define .startAt () and .endAt () for the previous job, is this date okay? Is possible summer time safe using this procedure?

 Calendar calTZStarts = new GregorianCalendar(TimeZone.getTimeZone("Pacific/Honolulu")); calTZStarts.set(2013, Calendar.JANUARY, 10); Calendar calTZEnds = new GregorianCalendar(TimeZone.getTimeZone("Pacific/Honolulu")); calTZEnds.set(2013, Calendar.JANUARY, 30); Calendar calStarts = Calendar.getInstance(); calStarts.set(Calendar.YEAR, calTZStarts.get(Calendar.YEAR)); calStarts.set(Calendar.MONTH, calTZStarts.get(Calendar.MONTH)); calStarts.set(Calendar.DAY_OF_MONTH, calTZStarts.get(Calendar.DAY_OF_MONTH)); calStarts.set(Calendar.HOUR_OF_DAY, calTZStarts.get(Calendar.HOUR_OF_DAY)); calStarts.set(Calendar.MINUTE, calTZStarts.get(Calendar.MINUTE)); calStarts.set(Calendar.SECOND, calTZStarts.get(Calendar.SECOND)); calStarts.set(Calendar.MILLISECOND, calTZStarts.get(Calendar.MILLISECOND)); Calendar calEnds = Calendar.getInstance(); calEnds.set(Calendar.YEAR, calTZEnds.get(Calendar.YEAR)); calEnds.set(Calendar.MONTH, calTZEnds.get(Calendar.MONTH)); calEnds.set(Calendar.DAY_OF_MONTH, calTZEnds.get(Calendar.DAY_OF_MONTH)); calEnds.set(Calendar.HOUR_OF_DAY, calTZEnds.get(Calendar.HOUR_OF_DAY)); calEnds.set(Calendar.MINUTE, calTZEnds.get(Calendar.MINUTE)); calEnds.set(Calendar.SECOND, calTZEnds.get(Calendar.SECOND)); calEnds.set(Calendar.MILLISECOND, calTZEnds.get(Calendar.MILLISECOND)); CronTrigger trigger = newTrigger() .withIdentity("name", "group") .withSchedule( cronSchedule("0 0 22 ? * *").inTimeZone(TimeZone.getTimeZone("Pacific/Honolulu")) ) .startAt(calStarts.getTime()) .endAt(calEnds.getTime()) .build(); 

or I just need to start and end using:

 Calendar calTZStarts = new GregorianCalendar(); calTZStarts.set(2013, Calendar.JANUARY, 10, 0, 0, 0); Calendar calTZEnds = new GregorianCalendar(); calTZEnds.set(2013, Calendar.JANUARY, 30, 0, 0, 0); CronTrigger trigger = newTrigger() .withIdentity("name", "group") .withSchedule( cronSchedule("0 0 22 ? * *").inTimeZone(TimeZone.getTimeZone("Pacific/Honolulu")) ) .startAt(calTZStarts.getTime()) .endAt(calTZEnds.getTime()) .build(); 

Then does the assignment begin / end correctly on certain Pacific / Honolulu days?

Thanks in advance for every suggestion.

+8
java timezone scheduled-tasks quartz-scheduler
source share
2 answers

I think I found a solution, tested and works until proven otherwise;)

RECUP My server runs in a specific time zone (i.e. In Europe / Rome)

If a user in Pacific / Honolulu TZ wants to schedule work that starts on Sun, January 27, 2013 at 15:00 ends at Thu, January 31, 2013 at 9:00 pm, which fires every day every five minutes, starting at 2: 00:00 - 22:55 (0 0/5 14-22 * *?) The correct way:

  • set user timezone in inTimeZone method to CronScheduleBuilder
  • adapt to server time startAt and endAt dates by moving from the Pacific / Honolulu to Europe / Rome.

Code example:

 // Begin User Input String userDefinedTZ = "Pacific/Honolulu"; // +11 int userStartYear = 2013; int userStartMonth = Calendar.JANUARY; int UserStartDayOfMonth = 27; int userStartHour = 15; int userStartMinute = 0; int userStartSecond = 0; int userEndYear = 2013; int userEndMonth = Calendar.JANUARY; int UserEndDayOfMonth = 31; int userEndHour = 21; int userEndMinute = 0; int userEndSecond = 0; // End User Input Calendar userStartDefinedTime = Calendar.getInstance(); // set start schedule by user input userStartDefinedTime.set(userStartYear, userStartMonth, UserStartDayOfMonth, userStartHour, userStartMinute, userStartSecond); Calendar userEndDefinedTime = Calendar.getInstance(); // set end schedule by user input userEndDefinedTime.set(userEndYear, userEndMonth, UserEndDayOfMonth, userEndHour, userEndMinute, userEndSecond); CronTrigger trigger = newTrigger() .withIdentity("name", "group") .withSchedule( // define timezone for the CronScheduleBuilder cronSchedule("0 0/5 14-22 * * ?").inTimeZone(TimeZone.getTimeZone("Pacific/Honolulu")) ) // adapt user start date to server timezone .startAt( convertDateToServerTimeZone(userStartDefinedTime.getTime(), userDefinedTZ) ) // adapt user end date to server timezone .endAt( convertDateToServerTimeZone(userEndDefinedTime.getTime(), userDefinedTZ) ) .build(); 

A utility for converting dates based on tz:

 public Calendar convertDateToServerTimeZone(Date dateTime, String timeZone) { Calendar userDefinedTime = Calendar.getInstance(); userDefinedTime.setTime(dateTime); if(!TimeZone.getDefault().getID().equalsIgnoreCase(timeZone)) { System.out.println ("original defined time: " + userDefinedTime.getTime().toString() + " on tz:" + timeZone); Calendar quartzStartDate = new GregorianCalendar(TimeZone.getTimeZone(timeZone)); quartzStartDate.set(Calendar.YEAR, userDefinedTime.get(Calendar.YEAR)); quartzStartDate.set(Calendar.MONTH, userDefinedTime.get(Calendar.MONTH)); quartzStartDate.set(Calendar.DAY_OF_MONTH, userDefinedTime.get(Calendar.DAY_OF_MONTH)); quartzStartDate.set(Calendar.HOUR_OF_DAY, userDefinedTime.get(Calendar.HOUR_OF_DAY)); quartzStartDate.set(Calendar.MINUTE, userDefinedTime.get(Calendar.MINUTE)); quartzStartDate.set(Calendar.SECOND, userDefinedTime.get(Calendar.SECOND)); quartzStartDate.set(Calendar.MILLISECOND, userDefinedTime.get(Calendar.MILLISECOND)); System.out.println("adapted time for " + TimeZone.getDefault().getID() + ": " + quartzStartDate.getTime().toString()); return quartzStartDate; } else { return userDefinedTime; } } 

== START UPDATES 2012-01-24 ==

Quartz Based Utility for tz-based date conversion using DateBuilder :

 public Calendar convertDateToServerTimeZone(Date dateTime, String timeZone) { Calendar userDefinedTime = Calendar.getInstance(); userDefinedTime.setTime(dateTime); if(!TimeZone.getDefault().getID().equalsIgnoreCase(timeZone)) { System.out.println("original defined time: " + userDefinedTime.getTime().toString() + " on tz:" + timeZone); Date translatedTime = DateBuilder.translateTime(userDefinedTime.getTime(), TimeZone.getDefault(), TimeZone.getTimeZone(timeZone)); Calendar quartzStartDate = new GregorianCalendar(); quartzStartDate.setTime(translatedTime); System.out.println("adapted time for " + TimeZone.getDefault().getID() + ": " + quartzStartDate.getTime().toString()); return quartzStartDate; } else { return userDefinedTime; } } 

== END OF UPDATE 2012-01-24 ==

So, on my Europe / Rome Quartz server, this work is scheduled for Monday from January 28, 02:00:00 CET 2013 to Friday February 1, 08:00:00 CET 2013 and fire every five minutes every day from 01:00 to 20 : 55

When creating your dates for beginning and ending time, also specify the time zone (in java.util.Calendar, or the date format or org.quartz.DateBuilder) before creating the date. The quartz then stores the date in milliseconds from January 1, 1970 in UTC in that particular time zone - and therefore, when the server’s time zone changes, the trigger does not affect.

+9
source share

The date does not carry any TZ data, and Daylight Savings Time is actually its own TZ (EST is the standard Easter time, EDT is the daylight saving time east time). The only thing that could be a problem is that some places like Phoenix Arizona do not recognize DST. Every time you need TZ data, a calendar is the way to go.

+1
source share

All Articles