我有一个对象正在从数据库加载配置。我使用日期时间字段(称为 GroupsLastRun
)存储上次运行作业的时间,并使用名为 Captureusersandgroups
的字符串字段存储作业应运行的频率。 Captureusersandgroups
存储三种不同的类型 'DAILY'、'WEEKLY' 和 'MONTHLY'。
基本上,我有一个循环应该只在作业要运行时才继续。到目前为止,我已经到了以下几点:
if (configEntity.GroupsLastrun > DateTime.Now.AddDays(-1) && configEntity.Captureusersandgroups == "DAILY") continue;
if (configEntity.GroupsLastrun > DateTime.Now.AddDays(-7) && configEntity.Captureusersandgroups == "WEEKLY") continue;
if (configEntity.GroupsLastrun > DateTime.Now.AddDays(-30) && configEntity.Captureusersandgroups == "MONTHLY") continue;
我确信(确定)有更好的方法来解决这个问题,但主要是作为一名 SQL Server 开发人员,我缺乏解决这个问题的批判性思维/工具。什么是更好的方法或我应该学习什么才能更好地考虑这个问题?
最佳答案
几点:
- 除非您想受制于时区和夏令时转换等,否则我会使用
DateTime.UtcNow
而不是DateTime.Now
(并确保您也存储 UTC 值) - 作为 p.s.w.g.提到过,只询问一次当前日期/时间是值得的 - 而不是性能,我想说重要的原因是一致性。在这种情况下,看起来您实际上只会使用其中一个值,但在其他情况下,我看到人们编写了同时使用两个评估的条件,如果代码在午夜运行会导致问题
- 由于同时检查条件和确定截止日期,您得到了重复代码。我会把两者分开。
所以,我会有这样的代码:
// Consider whether you actually want DateTime.UtcNow.Date
DateTime now = DateTime.UtcNow;
DateTime deadline;
switch (configEntity.Captureusersandgroups)
{
case "DAILY": deadline = now.AddDays(-1);
case "WEEKYLY": deadline = now.AddDays(-7);
case "MONTHLY": deadline = now.AddMonths(-1);
// I'm assuming there's *always* a schedule
default: throw new InvalidOperationException("Invalid schedule");
}
if (configEntity.GroupsLastrun > deadline)
{
continue;
}
请注意,从“现在”减去一个月与从“那时”增加一个月是不同的。例如,如果上一次运行是在 1 月 30 日,则下一次运行将在 3 月 1 日之前使用上述代码 - 而如果您将一个月添加到 1 月 30 日,它将在 2 月 28 日运行(除非您使用两个值的日期)。仔细考虑您想要的行为。
(作为一个快速插件,我显然还建议考虑我的 Noda Time 库来处理日期/时间。它可以更清楚地说明任何特定值是本地时间还是某个时区等。)
关于c# - 尝试将今天的日期与一个月前的日期进行比较,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15917757/