跨时区的Java Quartz-Scheduler

我的服务器在欧洲/罗马时区上运行-这是服务器上的默认tz-

我需要根据用户所在的时区安排工作,因此,如果居住在太平洋/檀香山时区的用户安排了一个CronTrigger每天下午22:00到达他所在的地球区域,我发现了以下解决方案:

CronTrigger trigger = newTrigger()

.withIdentity("name", "group")

.withSchedule(

cronSchedule("0 0 22 ? * *").inTimeZone(TimeZone.getTimeZone("Pacific/Honolulu"))

)

.startNow()

.build();

此工作 。

除了保持时区更新(即时区更新工具)外,还有一些特殊的问题需要考虑?

如果我想为上一份工作定义.startAt()和.endAt(),这种日期还可以吗?使用此过程可能会节省夏时制吗?

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();

或者我必须简单地设置开始和结束使用:

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();

然后,作业在“太平洋/檀香山”定义的日期正确开始/结束?

预先感谢您的每个建议

回答:

我想我找到了经过测试的解决方案,并且在证明没有问题之前一直有效;)

重新启动我的服务器在特定时区(即欧洲/罗马)上运行

如果Pacific / Honolulu

TZ上的用户要计划从Sun(2013年1月27日,下午3:00)开始的作业,结束于2013年1月31日(星期四),晚上9:00结束,则每天每五分钟从2:00

PM到10:55 PM(0 0/5 14-22 * *?)正确的方法如下:

  • 在CronScheduleBuilder的inTimeZone方法中设置用户时区
  • 从太平洋/火奴鲁鲁转换为欧洲/罗马以适应服务器时间startAt和endAt日期

样例代码:

// 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();

用于根据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;

}

}

==开始更新2012-01-24 ==

基于Quartz的实用程序,使用DateBuilder基于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);

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;

}

}

==更新结束2012-01-24 ==

因此,

在为开始时间和结束时间构建日期时,还应在实例化日期之前指定时区(在java.util.Calendar上,或在日期格式字符串上,或在org.quartz.DateBuilder上)。然后,石英在该特定时区中以UTC格式存储了自1970年1月1日起的毫秒数,因此,当服务器的时区更改时,触发器不会受到影响。

以上是 跨时区的Java Quartz-Scheduler 的全部内容, 来源链接: utcz.com/qa/418911.html

回到顶部