0

背景:

我正在尝试安排一项任务,以便在项目中向我的用户发送邮件。我想通过每天美国东部标准时间凌晨 2 点发送邮件来自动执行此任务。

我的代码:

我真的想不出一个好的代码,但我正在这样做:

 DateTime.Now.AddHours(hours);

但问题是,当我将此代码部署到服务器时,它需要DateTime.Now部署时间并增加hours该时间。

我怎样才能找到一个干净的解决方案?

4

3 回答 3

3

要使用当地时间,您需要时区:

var timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");

要获取您以当地时间表示的计划时间,您需要获取当前本地时间并决定下一次计划的时间:

var estNow = TimeZoneInfo.ConvertTimeFromUtc(DateTime.UtcNow, timeZoneInfo);
var estScheduleAt = estNow.Date + TimeSpan.FromHours(2);

现在estScheduleAt是美国东部标准时间今天凌晨 2 点。如果此代码在美国东部标准时间上午 12 点到凌晨 2 点之间执行,您应该在此时安排下一个操作。但是,如果当前时间在美国东部标准时间凌晨 2 点之后,您应该安排在明天凌晨 2 点(仍在美国东部标准时间),因此您需要在时间上增加一天:

if (estScheduleAt <= estNow)
  estScheduleAt += TimeSpan.FromDays(1);

如果该算法在美国东部标准时间凌晨 2 点之前运行,则该算法可能会失败,因为谓词estScheduleAt <= estNow为真,但在计划操作之前它是过去的。您可能需要针对这种情况添加一些额外的处理。

在安排操作之前,您应该转换回 UTC 以避免任何时区问题:

var scheduleAt = TimeZoneInfo.ConvertTimeToUtc(estScheduleAt, timeZoneInfo);

现在,您可以将scheduleAt时间戳与您的调度程序一起使用,以使您的操作在美国东部标准时间下一个凌晨 2 点运行。

于 2013-10-14T11:24:02.117 回答
0

使用 DateTime.UtcNow 并添加小时数。

最好在 UTC 时间做所有事情,并在代码入口和出口点将其转换为本地时间。

于 2013-10-14T11:17:49.857 回答
0

我已经完成了Quartz.Net 调度程序

对于配置,我使用CronMaker进行表达式

示例代码

// construct a scheduler factory
ISchedulerFactory schedFact = new StdSchedulerFactory();

// get a scheduler
IScheduler sched = schedFact.GetScheduler();
sched.Start();

// construct job info
JobDetail jobDetail = new JobDetail("myJob", null, typeof(HelloJob));
// fire every hour
Trigger trigger = TriggerUtils.MakeHourlyTrigger();
// start on the next even hour
trigger.StartTimeUtc = TriggerUtils.GetEvenHourDate(DateTime.UtcNow);  
trigger.Name = "myTrigger";
sched.ScheduleJob(jobDetail, trigger); 

在 asp.net 网站中检查Quartz.net 设置

于 2013-10-14T11:27:15.483 回答