我想我找到了经过测试的解决方案,并且在证明没有问题之前一直有效;)
重新启动我的服务器在特定时区(即欧洲/罗马)上运行
如果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 InputString userDefinedTZ = "Pacific/Honolulu"; // +11int 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 InputCalendar userStartDefinedTime = Calendar.getInstance();// set start schedule by user inputuserStartDefinedTime.set(userStartYear, userStartMonth, UserStartDayOfMonth, userStartHour, userStartMinute, userStartSecond);Calendar userEndDefinedTime = Calendar.getInstance();// set end schedule by user inputuserEndDefinedTime.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 ==
因此, 在我的Europe / Rome Quartz服务器上,此作业计划从2013年1月28日星期一02:00:00
CET开始,到2013年2月1日星期五CET 2013开始,并且每天从01:00 AM到08每隔五分钟触发一次: 55PM
在为开始时间和结束时间构建日期时,还应在实例化日期之前指定时区(在java.util.Calendar上,或在日期格式字符串上,或在org.quartz.DateBuilder上)。然后,石英在该特定时区中以UTC格式存储了自1970年1月1日起的毫秒数,因此,当服务器的时区更改时,触发器不会受到影响。



