Cri*_*rta 9 java timezone scheduled-tasks quartz-scheduler
我的服务器在欧洲/罗马时区运行 - 这个是服务器上的默认tz,我需要根据用户的时区安排工作,因此,如果居住在太平洋/檀香山时区的用户安排一个CronTrigger,每个人都会触发我发现这个解决方案的一天是晚上22点为他的地球区域:
CronTrigger trigger = newTrigger()
.withIdentity("name", "group")
.withSchedule(
cronSchedule("0 0 22 ? * *").inTimeZone(TimeZone.getTimeZone("Pacific/Honolulu"))
)
.startNow()
.build();
Run Code Online (Sandbox Code Playgroud)
在我的服务器上,这个工作从第二天"我的"上午09:00开始.
除了保持更新时区(即时区更新工具)之外,还有一些特殊问题需要考虑吗?
如果我想为前一个作业定义.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();
Run Code Online (Sandbox Code Playgroud)
或者我必须设置简单的开始和结束使用:
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();
Run Code Online (Sandbox Code Playgroud)
然后,工作在"太平洋/檀香山"定义的日子里正确开始/结束?
提前感谢您的每一个建议
Cri*_*rta 10
我想我找到了解决方案,经过测试,直到证明不是这样的;)
Recup我的服务器在特定时区(即欧洲/罗马)运行
如果太平洋/檀香山TZ上的用户想要安排在Sun开始的工作,2013年1月27日下午3:00结束于2013年1月31日星期四晚上9点,每天从下午2:00开始,每隔5分钟开始一次10:55 PM(0 0/5 14-22**?)正确的方法如下:
示例代码:
// 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();
Run Code Online (Sandbox Code Playgroud)
用于根据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;
}
}
Run Code Online (Sandbox Code Playgroud)
Quartz Based Utility使用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;
}
}
Run Code Online (Sandbox Code Playgroud)
所以在我的欧洲/罗马Quartz服务器上,这份工作计划从2013年1月28日02:00:00 CET到2013年6月1日星期五08:00:00 CET开始,每天从凌晨01:00到08每隔5分钟开始一次: 55PM
在为开始和结束时间构建日期时,还要在实例化Date之前指定时区(在java.util.Calendar或日期格式字符串或org.quartz.DateBuilder上).然后,quartz将日期自1970年1月1日起以UTC为单位存储在该特定时区的UTC中 - 因此当服务器的时区发生变化时,触发器不会受到影响.
| 归档时间: |
|
| 查看次数: |
19732 次 |
| 最近记录: |