我有一个解决方法 - 它不漂亮。我有类似的情况:用户选择一天/天来运行我们的服务,我们每 x 分钟轮询一次。这意味着我需要安排轮询器在用户当天运行(基于他们的时区)。所以我创建了 1 个或 2 个(很可能是 2 个)触发器来覆盖用户的一天。
示例:用户希望在星期四运行服务,并且他们在美国/芝加哥时区,我将创建 2 个 DailyTimeInterval 触发器来覆盖这一天
正式
美国/芝加哥开始:4/28/16 12:00:00 AM CDT,结束:4/28/16 11:59:59 PM CDT
,相当于
UTC 开始:4/28/16 5:00:00上午 UTC,结束时间:2016 年 4 月 29 日凌晨 4:59:59 UTC
第一个触发器将从 UTC 星期四 5:00:00 运行到 23:59:59 第二个触发器将从 UTC 星期五 0:00:00 运行到 4:59:59
这是我的 Java 7 代码的样子
//SDF_DAY_TO_CALENDAR_DAY is a hashmap that translates from simpledateformat day of week to calendar
//simple date format day number of the week is 1=Monday 7=Sunday
//calendar day number is 1=Sunday 7=Saturday
private static final Map<Integer, Integer> SDF_DAY_TO_CALENDAR_DAY = Collections.unmodifiableMap(new HashMap<Integer, Integer>() {{
put(1, Calendar.MONDAY);
put(2, Calendar.TUESDAY);
put(3, Calendar.WEDNESDAY);
put(4, Calendar.THURSDAY);
put(5, Calendar.FRIDAY);
put(6, Calendar.SATURDAY);
put(7, Calendar.SUNDAY);
}});
private Set<Trigger> createTrigger(Integer dayOfWeek, TimeZone usersTimeZone) {
Calendar startOfDay = Calendar.getInstance(usersTimeZone);
Calendar endOfDay = Calendar.getInstance(usersTimeZone);
startOfDay.set(Calendar.HOUR_OF_DAY, 0);
startOfDay.set(Calendar.MINUTE, 0);
startOfDay.set(Calendar.SECOND, 0);
startOfDay.set(Calendar.DAY_OF_WEEK, dayOfWeek);
endOfDay.set(Calendar.HOUR_OF_DAY, 23);
endOfDay.set(Calendar.MINUTE, 59);
endOfDay.set(Calendar.SECOND, 59);
endOfDay.set(Calendar.DAY_OF_WEEK, dayOfWeek);
SimpleDateFormat hour = new SimpleDateFormat("H");
SimpleDateFormat minute = new SimpleDateFormat("m");
SimpleDateFormat second = new SimpleDateFormat("s");
SimpleDateFormat day = new SimpleDateFormat("u"); //Monday = 1, Sunday = 7
hour.setTimeZone(getTimeZone("UTC"));
minute.setTimeZone(getTimeZone("UTC"));
second.setTimeZone(getTimeZone("UTC"));
day.setTimeZone(getTimeZone("UTC"));
Integer utcStartHour = Integer.valueOf(hour.format(startOfDay.getTime()));
Integer utcStartMinute = Integer.valueOf(minute.format(startOfDay.getTime()));
Integer utcStartSecond = Integer.valueOf(second.format(startOfDay.getTime()));
Integer utcStartDay = Integer.valueOf(day.format(startOfDay.getTime()));
Integer utcEndHour = Integer.valueOf(hour.format(endOfDay.getTime()));
Integer utcEndMinute = Integer.valueOf(minute.format(endOfDay.getTime()));
Integer utcEndSecond = Integer.valueOf(second.format(endOfDay.getTime()));
Integer utcEndDay = Integer.valueOf(day.format(endOfDay.getTime()));
Set<Trigger> triggersForJob;
if (!utcStartDay.equals(utcEndDay)) {
TimeOfDay trigger1StartTime = new TimeOfDay(utcStartHour, utcStartMinute, utcStartSecond);
TimeOfDay trigger1EndTime = new TimeOfDay(23, 59, 59);
Trigger firstTrigger = newTrigger()
.withIdentity("trigger 1", "group")
.withSchedule(dailyTimeIntervalSchedule()
.withIntervalInMinutes(pollingIntervalInMinutes)
.onDaysOfTheWeek(SDF_DAY_TO_CALENDAR_DAY.get(utcStartDay))
.startingDailyAt(trigger1StartTime)
.endingDailyAt(trigger1EndTime))
.startAt(futureDate(pollingIntervalInMinutes, DateBuilder.IntervalUnit.MINUTE))
.build();
TimeOfDay trigger2StartTime = new TimeOfDay(0, 0, 0);
TimeOfDay trigger2EndTime = new TimeOfDay(utcEndHour, utcEndMinute, utcEndSecond);
Trigger secondTrigger = newTrigger()
.withIdentity("trigger 2", "group")
.withSchedule(dailyTimeIntervalSchedule()
.withIntervalInMinutes(pollingIntervalInMinutes)
.onDaysOfTheWeek(SDF_DAY_TO_CALENDAR_DAY.get(utcEndDay))
.startingDailyAt(trigger2StartTime)
.endingDailyAt(trigger2EndTime))
.startAt(futureDate(pollingIntervalInMinutes, DateBuilder.IntervalUnit.MINUTE))
.build();
triggersForJob = Sets.newHashSet(firstTrigger, secondTrigger);
} else {
TimeOfDay triggerStartTime = new TimeOfDay(utcStartHour, utcStartMinute, utcStartSecond);
TimeOfDay triggerEndTime = new TimeOfDay(utcEndHour, utcEndMinute, utcEndSecond);
Trigger trigger = newTrigger()
.withIdentity("trigger", "group")
.withSchedule(dailyTimeIntervalSchedule()
.withIntervalInMinutes(pollingIntervalInMinutes)
.onDaysOfTheWeek(SDF_DAY_TO_CALENDAR_DAY.get(utcStartDay))
.startingDailyAt(triggerStartTime)
.endingDailyAt(triggerEndTime))
.startAt(futureDate(pollingIntervalInMinutes, DateBuilder.IntervalUnit.MINUTE))
.build();
triggersForJob = Sets.newHashSet(trigger);
}
return triggersForJob;
}