brain storm
brain storm

Reputation: 31252

how to handle user timezone for daylight savings in quartz for cron Triggers?

My service api takes in startDate for quartz Job and day of Month for the job to executed. Internally, I convert this to cron expression and save in quartz.

For example, a user in PST submits a job request today (Nov 3 2017) as follows.

{
"start": "2017-11-03T18:00:00-07:00",
"dayOfMonth" : 15
}

Here the user wants to schedule a job that fires on 15th of each month at 6 PM, starting from 2017-11-03. so the first-day quartz will fire will be 2017-11-15. This is how the above request gets converted to cron expression 0 0 18 15 * ? *, which is correct. Here is how, QRTZ_CRON_TRIGGERS table looks like.

enter image description here

As you notice, time_zone_id is saved as GMT-07:00, but once daylight savings kick-in on Nov 5, it must be GMT-08:00. or else my quartz job will fire one hour earlier. In fact, when I query for nextFireTime, I do get 1510794000000 which is indeed Wednesday November 15, 2017 17:00:00 (pm) in time zone America/Los Angeles (PST)

how do we handle this time_zone_id issue?

P.S: I am using cronTrigger which does not have the notion of preserveHourOfDayAcrossDaylightSavings that is provided by CalendarIntervalTrigger.

Upvotes: 3

Views: 3787

Answers (2)

techStud
techStud

Reputation: 318

You can use ZonedDateTime from java8/java8+, In that way you will not need to explicitly convert the given time into server specific time and it also takes care of daylight saving timezones:

protected static Trigger createCronTrigger(String triggerName, ZonedDateTime startTime, String cronExpression, int misFireInstruction, ZoneId timeZone) {
    Trigger trigger = TriggerBuilder.newTrigger()
        .withIdentity(triggerName)
        .startAt(Date.from(startTime.toInstant())).withSchedule(CronScheduleBuilder.cronSchedule(cronExpression).inTimeZone(TimeZone.getTimeZone(timeZone)).withMisfireHandlingInstructionDoNothing())
        .build();
    return trigger;
}

Upvotes: 0

Srinivas
Srinivas

Reputation: 400

Do not use offset to represent the timezone. Rather you can ask the user to pass in timezone like "America/Los_Angeles". Then you can use http://www.quartz-scheduler.org/api/2.2.1/org/quartz/CronScheduleBuilder.html#inTimeZone(java.util.TimeZone) to create trigger with proper timezone.

inTimeZone(TimeZone.getTimeZone("USER_ENTERED_VALUE")

Finally when you look at QRTZ_CRON_TRIGGERS table, the value for TIME_ZONE_ID will be America/Los_Angeles

Upvotes: 3

Related Questions