使用 Quartz.net Server 版本 2.1.2,由于缺乏对 UTC 时区偏移的支持,我从 2.0 版本升级到该版本。在我们指定的时间没有发送作业,这似乎是因为时区偏移。
我有三种工作类型:
工作频率要求
- 每天(每天在给定时间一次)
- 每周(1 到 N 天,每天在给定时间一次)
- 每月(1 到 n 天、每天一次或最后一天)
对于这三个,我将 Cron 表达式与SimpleTriggers一起使用。
我的问题是: 我需要勾选哪些内容来验证我正在安排的作业以及将在服务器上运行的作业是否会在其时区按时运行?
似乎仅仅指定时区是不够的;我这样指定时区
dailyTrigger.TimeZone = BrainTimeZone;
但是在保存石英实例(在 PST 中)的服务器上,在纽约(美国东部标准时间)下午 2:00 安排了一项工作,“下一次运行时间”应该是下午 2:00,但它显示并在中午运行。
这里有几篇关于 Quartz Time Zones 的优秀 s/o 文章:
Quartz.net UTC 资源:
这是我目前每天安排的方式:
private void CreateDaily()
{
var expression = CronScheduleBuilder
.DailyAtHourAndMinute(GetNormalizedHour(), Minute)
.InTimeZone(TimeZone)
.Build() as CronTriggerImpl;
IJobExecutionContext jobContext = GetJobContext();
IJobDetail job = JobBuilder.Create<MailJob>()
.WithIdentity(JobName, GroupName)
.UsingJobData(jobContext.JobDetail.JobDataMap)
.Build();
ScheduleBuilder<>cronExpressionString
var cronExpressionString = expression.CronExpressionString; // returns a cron expr.
var dailyTrigger = (ICronTrigger)TriggerBuilder.Create()
.WithIdentity(JobName, GroupName)
.WithSchedule(cronExpressionString)
.Build();
dailyTrigger.TimeZone = BrainTimeZone;
this.JobTrigger = dailyTrigger;
this.JobDetail = job;
this.Success = true;
}
我尝试使用 DailyTimeIntervalTriggerImpl,但这似乎不是上述 3 种间隔类型中的任何一种的正确触发器。
private void DailyJob()
{
#region Duration
var daysOfWeek = new Quartz.Collection.HashSet<System.DayOfWeek>
{
System.DayOfWeek.Monday,
System.DayOfWeek.Tuesday,
System.DayOfWeek.Wednesday,
System.DayOfWeek.Thursday,
System.DayOfWeek.Friday,
System.DayOfWeek.Saturday,
System.DayOfWeek.Sunday,
};
DateTimeOffset startTime = DateTime.Now;
DateTimeOffset endTime = DateTime.Now.AddYears(1);
TimeOfDay startTimeOfDay = TimeOfDay.HourMinuteAndSecondOfDay(Hour, Minute, 0);
TimeOfDay endTimeOfDay = TimeOfDay.HourMinuteAndSecondOfDay(Hour, Minute, 30);
#endregion
IJobExecutionContext jobContext = GetJobContext();
if (JobName == null || GroupName == null) {
this.Success = false;
return;
}
var dailyTrigger = new DailyTimeIntervalTriggerImpl
{
StartTimeUtc = startTime.ToUniversalTime(),
EndTimeUtc = endTime.ToUniversalTime(),
StartTimeOfDay = startTimeOfDay,
EndTimeOfDay = endTimeOfDay,
RepeatIntervalUnit = IntervalUnit.Week,
DaysOfWeek = daysOfWeek,
// RepeatInterval = 1,
TimeZone = TimeZone,
Key = new TriggerKey(JobName, GroupName),
};
// Compute fire times just to show simulated fire times
IList<DateTimeOffset> fireTimes = TriggerUtils.ComputeFireTimes(dailyTrigger, null, 1000);
foreach (var dateTimeOffset in fireTimes)
{
QuartzLog("Daily trigger has been computed - fireTimes as follows:\r\n\r\n");
QuartzLog(string.Format("utc:{0} - adjusted time:{1} - timezone:{2}", dateTimeOffset,
TimeZoneInfo.ConvertTimeFromUtc(dateTimeOffset.DateTime, BrainTimeZone), BrainTimeZone.DisplayName));
}
我正在重构我的所有石英层,因此我正在寻找最佳实践和一种防弹方法,以确保作业将在我们指定的时间运行,无论 Quartz.net 作业服务器位于何处,以及在何处用户的时区起源于他们希望它最终到达的地方。
我们正在将我们的quartz.net 服务器移至AWS,因此我们将拥有一个分布式服务器场来托管这些服务器,其时区可能会发生变化。
如何设置我的石英架构,使其足够动态,并且如上所述,防弹,按时发送作业 - 无论 TimeZones / Offsets / DaylightSavings / LeapYear / Sleat / Snow / Rain / Zombie Attacks / Y2K /流星 ELE / 等 ?
谢谢你。