我正在检查Quartz.Net的cron触发器并注意到当我每小时使用任何其他触发器时,它会将时间偏移到UTC(应该总是如此),但是当我为每小时做同样的事情时cron,它选择当地时间。
例如
假设我的开始时间为2014-05-31 15:44:00
接下来的6次每小时时间表
Cron Expression:
0 0 0/1 1/1 * ? *
以
命名5/31/2014 5:30:00 PM +00:00
5/31/2014 6:30:00 PM +00:00
5/31/2014 7:30:00 PM +00:00
5/31/2014 8:30:00 PM +00:00
5/31/2014 9:30:00 PM +00:00
5/31/2014 10:30:00 PM +00:00
显示当地时间。
但是,当我尝试说每周时间表
时Cron:
0 44 15 ? * SUN,MON *
时间表显示为
6/1/2014 10:14:00 AM +00:00
6/2/2014 10:14:00 AM +00:00
6/8/2014 10:14:00 AM +00:00
6/9/2014 10:14:00 AM +00:00
6/15/2014 10:14:00 AM +00:00
6/16/2014 10:14:00 AM +00:00
哪个偏向UTC,这是正确的。
这是我正在使用的代码
var cron = new Quartz.CronExpression("0 0 0/1 1/1 * ? *");
DateTimeOffset? nextFire = cron.GetNextValidTimeAfter(Convert.ToDateTime("5/31/2014 4:30:00 PM"));
显然,我动态更改了参数。
这是执行计划计算的代码
var jobItem = (DbContext.jobs.Where(job => job.Id == id)).FirstOrDefault();
List<DateTimeOffset> scheduleTimes = new List<DateTimeOffset>();
var time = DateTimeOffset.Now;
if (!string.IsNullOrEmpty(jobItem.CronExpression))
{
for (int i = 0; i <= 5; i++)
{
var date = GetScheduleForCron(jobItem.CronExpression, time);
scheduleTimes.Add(date.Value);
time = date.Value;
}
}
else
{
var jobAttribute =
(from attribute in DbContext.jobattributes
where attribute.JobId == jobItem.Id
select attribute.SpecificDate).FirstOrDefault();
scheduleTimes.Add(jobAttribute.Value);
}
public static DateTimeOffset? GetScheduleForCron(string cronexpression, DateTimeOffset date)
{
var cron = new CronExpression(cronexpression);
return cron.GetNextValidTimeAfter(date.DateTime);
}
编辑:我使用http://www.cronmaker.com/来验证我的日程安排。
答案 0 :(得分:1)
您可能会混淆使用本地和UTC时间。特别是如果您有Convert.ToDateTime("5/31/2014 4:30:00 PM")
,DateTimeOffset.Now
或date.DateTime
。 Quartz的一般规则是
UTC时间进入,UTC时间出来
。这是使用预期输出运行您的案例的示例(为简洁起见使用了非构建器API):
var firstTrigger = new CronTriggerImpl();
firstTrigger.CronExpressionString = "0 0 0/1 1/1 * ? *";
firstTrigger.StartTimeUtc = new DateTime(2014, 05, 31, 15, 44, 00).ToUniversalTime();
Console.WriteLine("first trigger fire times:");
Console.WriteLine(string.Join(Environment.NewLine, TriggerUtils.ComputeFireTimes(firstTrigger, null, 6).Select(x => x.ToLocalTime())));
var secondTrigger = new CronTriggerImpl();
secondTrigger.CronExpressionString = "0 44 15 ? * SUN,MON *";
secondTrigger.StartTimeUtc = new DateTime(2014, 05, 31, 15, 44, 00).ToUniversalTime();
Console.WriteLine("second trigger fire times:");
Console.WriteLine(string.Join(Environment.NewLine, TriggerUtils.ComputeFireTimes(secondTrigger, null, 6).Select(x => x.ToLocalTime())));
它将输出(在我的GMT + 3语言环境中,默认情况下,cron触发器在当前语言环境的时区运行):
first trigger fire times
31.5.2014 16:00:00 +03:00
31.5.2014 17:00:00 +03:00
31.5.2014 18:00:00 +03:00
31.5.2014 19:00:00 +03:00
31.5.2014 20:00:00 +03:00
31.5.2014 21:00:00 +03:00
second trigger fire times:
1.6.2014 15:44:00 +03:00
2.6.2014 15:44:00 +03:00
8.6.2014 15:44:00 +03:00
9.6.2014 15:44:00 +03:00
15.6.2014 15:44:00 +03:00
16.6.2014 15:44:00 +03:00