Cron在Quartz.Net中触发每小时值

时间:2014-05-31 11:09:01

标签: c# quartz.net

我正在检查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/来验证我的日程安排。

1 个答案:

答案 0 :(得分:1)

您可能会混淆使用本地和UTC时间。特别是如果您有Convert.ToDateTime("5/31/2014 4:30:00 PM")DateTimeOffset.Nowdate.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