Quartz.Net 如何创建每天不增加 1 分钟的日程安排

Posted

技术标签:

【中文标题】Quartz.Net 如何创建每天不增加 1 分钟的日程安排【英文标题】:Quartz.Net how to create a daily schedule that does not gain 1 minute per day 【发布时间】:2012-09-25 23:45:33 【问题描述】:

我正在尝试在 Quartz.Net 中建立一个重复的每日计划,但有一些问题:

首先,我制定了一个每日计划,在 12:45 重播 像这样使用 Quartz.Net 代码:

var trigger = TriggerBuilder.Create()
  .WithDailyTimeIntervalSchedule(s => 
      s.OnEveryDay().StartingDailyAt(new TimeOfDay(13, 00)))
.Build();

var times = TriggerUtils.ComputeFireTimes(trigger as IOperableTrigger, null, 10);

foreach (var time in times) Console.WriteLine(time);

这是在新西兰执行,DST(所以 UTC+13:00)

我得到的输出很奇怪:

5/10/2012 1:00:00 p.m. +13:00
5/10/2012 12:01:00 a.m. +00:00
5/10/2012 12:02:00 a.m. +00:00
5/10/2012 12:03:00 a.m. +00:00
5/10/2012 12:04:00 a.m. +00:00
5/10/2012 12:05:00 a.m. +00:00
5/10/2012 12:06:00 a.m. +00:00
5/10/2012 12:07:00 a.m. +00:00
5/10/2012 12:08:00 a.m. +00:00
5/10/2012 12:09:00 a.m. +00:00

第一个日期/时间使用本地时区显示,其余时间使用UTC显示,每个时间值增加1分钟,日期不变。

我觉得我可能在每日时间间隔时间表中遗漏了一些基本的东西,但我只是不知道它是什么?

编辑

作为执行此操作的更新,我现在已切换到使用基于 CRON 表达式的触发器:

TriggerBuilder.Create()
  .WithCronSchedule(string.Format("0 0 1 ? * *", 0, 13))
  .Build();

它给了我预期的结果:

5/10/2012 12:00:00 a.m. +00:00
6/10/2012 12:00:00 a.m. +00:00
7/10/2012 12:00:00 a.m. +00:00
8/10/2012 12:00:00 a.m. +00:00
9/10/2012 12:00:00 a.m. +00:00
10/10/2012 12:00:00 a.m. +00:00
11/10/2012 12:00:00 a.m. +00:00
12/10/2012 12:00:00 a.m. +00:00
13/10/2012 12:00:00 a.m. +00:00
14/10/2012 12:00:00 a.m. +00:00

但我仍然想知道为什么 DailyTimeIntervale 计划不起作用...

【问题讨论】:

TriggerUtils.ComputeFireTimes -- 太棒了! 【参考方案1】:

虽然WithIntervalInHours 可能会解决这个问题,并且类似 cron 的计划更加灵活,但我想分享另一个解决方案:EndingDailyAfterCount(...)

var trigger = TriggerBuilder.Create()
  .WithDailyTimeIntervalSchedule(s => s
      .OnEveryDay()
      .StartingDailyAt(TimeOfDay.HourAndMinuteOfDay(13, 00)))
      .EndingDailyAfterCount(1))
.Build();

【讨论】:

很好......这也以一种非常优雅的方式解决了夏令时问题! @AndreasNiedermair 很高兴我能帮上忙,仅就我个人的知识而言:quartz.net 的 cron 之类的时间表是否有任何 dst 问题? 啊,据我所知:内部时间存储在 UTC 中,因此与 DST 完全无关 - 可能您必须在 DST 更改后重新安排作业以反映相关 UTC 时间戳的更改。 ..(但我不知道在添加 cron 表达式时会添加哪个扩展 - 未来 - 触发器,或者它们是否被动态评估) EndingDailyAfterCount是什么意思? @Mou 这将在 x 次运行后停止每天的计划。如果您想安排一个作业从早上 8 点到晚上 8 点每小时运行一次,您可以使用 OnEveryDay().StartingDailyAt(TimeOfDay.HourAndMinuteOfDay(8, 0)).WithIntervalInHours(1).EndingDailyAfter(12)【参考方案2】:

您没有指定默认为 1 分钟的间隔,因此它假定您希望每分钟运行一次作业。

试试

 ITrigger trigger = TriggerBuilder.Create()
    .WithDailyTimeIntervalSchedule
      (s => 
         s.WithIntervalInHours(24)
        .OnEveryDay()
        .StartingDailyAt(TimeOfDay.HourAndMinuteOfDay(13, 0))
      )
    .Build();

默认应该是每天运行,所以 OnEveryDay() 并不是真正需要的。

不知道为什么你会看到本地和 UTC,因为我所有的时间都以 UTC 显示。

【讨论】:

Daylight Svaing Time 不会有问题吗? (见here) 我对此有更多疑问,如果我想每天在上午 12 点和下午 12 点开始两次,我该怎么做? @NguyễnHuy。我猜ITrigger trigger = TriggerBuilder.Create() .WithDailyTimeIntervalSchedule (s => s.WithIntervalInHours(12)) .Build();ITrigger trigger = TriggerBuilder.Create() .WithDailyTimeIntervalSchedule (s => s.WithIntervalInHours(12) .OnEveryDay() .StartingDailyAt(TimeOfDay.HourAndMinuteOfDay(0, 0)) ) .Build(); @sgmoore:我给了一个时间来举例,所以你可能误解了我的意思,我的意思是如何在每天设置多个时间。例如:凌晨 2 点;凌晨 3 点;凌晨 5 点。这些时间的时间段不同。 刚给自己发了 14600 封邮件该死。

以上是关于Quartz.Net 如何创建每天不增加 1 分钟的日程安排的主要内容,如果未能解决你的问题,请参考以下文章

定时调度系列之Quartz.Net详解(转)

TopShelf+Quartz.net实现基于window服务的定时调度

如何创建一个Quartz.NET的工作,需要注射autofac

quartz.net 时间表达式----- Cron表达式详解

crontab怎样每隔5分钟执行一次脚本

如何 Scale Up/Down 应用?- 每天5分钟玩转 Docker 容器技术(126)