4

使用 Java Quartz 2.2.1,我无法为 DailyTimeIntervalTrigger 找到对备用(例如系统默认除外)时区的支持。它是否存在,或者有人知道解决方法吗?

例如,我想做这样的事情:

DailyTimeIntervalTrigger t = newTrigger()
    .withSchedule(
        dailyTimeIntervalSchedule()
            .startingDailyAt(new TimeOfDay(8, 0))
            .withIntervalInMinutes(15)
            .endingDailyAfterCount(3)
            .inTimeZone(TimeZone.getTimeZone("America/Los_Angeles"))
            // inTimeZone not present on DailyTimeIntervalScheduleBuilder
    )
    .build();
4

3 回答 3

0

检查 DailyTimeIntervalScheduleBuilder http://quartz-scheduler.org/api/2.2.0/org/quartz/DailyTimeIntervalScheduleBuilder.html

应该会有所帮助

添加您自己的 TimeZone 处理自定义逻辑,它应该能够根据服务器时区和您打算执行的时区增加或减少执行时间。

例如,我的服务器在 GMT 运行,我的业务在太平洋标准时间下午 6:00 结束。

为了解决这个问题,我只需添加/减去一个固定数字来补偿时区差异。

于 2013-11-09T00:37:34.217 回答
0

您可以在为startingDailyAt()方法初始化TimeOfDay对象时指定适当的时区。 例如:

Date startDate = new Date(Date.UTC(2018, 9, 13, 12, 00, 00));
Date endDate = new Date(Date.UTC(2018, 9, 13, 23, 00, 00));

return TriggerBuilder.newTrigger()
            .withSchedule(dailyTimeIntervalSchedule()
                    .startingDailyAt(TimeOfDay.hourAndMinuteFromDate(startDate, TimeZone.getTimeZone("America/New_York")))
                    .endingDailyAt(TimeOfDay.hourAndMinuteFromDate(endDate, TimeZone.getTimeZone("America/New_York")))
                    .onDaysOfTheWeek(MONDAY_THROUGH_FRIDAY)
                    .withInterval(10, DateBuilder.IntervalUnit.MINUTE))
            .build();

但请记住,您必须以UTC表示startDateendDate的时间。
在这种情况下,上述触发器将在纽约时间每个工作日的上午 8 点到晚上 7 点开始。

于 2018-09-14T09:16:39.790 回答
0

我有一个解决方法 - 它不漂亮。我有类似的情况:用户选择一天/天来运行我们的服务,我们每 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;
        }
于 2016-04-27T15:21:09.527 回答