首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >尝试将今天的日期与一个月前的日期进行比较

尝试将今天的日期与一个月前的日期进行比较
EN

Stack Overflow用户
提问于 2013-04-10 13:35:43
回答 3查看 938关注 0票数 2

我有一个从数据库加载配置的对象。我使用datetime字段(名为GroupsLastRun)存储作业的最后运行时间,并使用名为Captureusersandgroups的字符串字段存储作业运行的频率。Captureusersandgroups存储了三种不同的类型“每日”、“每周”和“每月”。

基本上,我有一个循环应该只在作业即将运行时才会继续。到目前为止,我已经谈到了以下几点:

代码语言:javascript
运行
复制
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开发人员,我主要缺乏批判性思维/工具来实现这一点。什么是更好的方法,或者我应该学习什么,这样我才能更好地思考这个问题?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-04-10 14:06:43

以下是几点:

  • 除非你想受时区和夏令时转换等的支配,否则我会使用DateTime.UtcNow而不是DateTime.Now (并确保你也将UTC值存储为p.s.w.g )
  • 。如上所述,只需要询问当前日期/时间一次是值得的-但与性能相比,我会说重要的原因是一致性。在这种情况下,看起来你实际上只使用其中一个值,但在其他情况下,我见过人们编写同时使用两个求值的条件,如果在midnight
  • You've上运行代码会导致问题,因为同时检查条件和确定截止日期而获得重复代码。我会把这两个分开。

所以,我会有这样的代码:

代码语言:javascript
运行
复制
// 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;
}

请注意,从"now“中减去一个月与从"then”中添加一个月是不同的。例如,如果最后一次运行是在1月30日,那么使用上面的代码,下一次运行将不会是3月1日-而如果您将一个月添加到1月30日,则下一次运行将在2月28日(除非您使用这两个值的日期)。仔细考虑你想要的行为。

(作为一个快速插件,我显然还建议将我的Noda Time库用于日期/时间工作。它使任何特定值是本地时间,还是在某个时区等更清晰。)

票数 7
EN

Stack Overflow用户

发布于 2013-04-10 13:52:53

两点:

  1. DateTime.Now可以(潜在地)在每次调用时返回不同的日期。它也不是很快。通过只调用一次,您将获得更好的一致性和非常轻微的性能提升。
  2. 你可能应该使用标准的方法来添加周和月,为了一致性(例如,一个月中并不总是有30天)和全球化(例如,不是所有的文化都有7天一周)。请注意,没有简单的方法可以单独使用DateTime添加周数;您必须使用Calendar来代替。

试试这个:

代码语言:javascript
运行
复制
var now = DateTime.UtcNow; // See Jon Skeet's answer
var cal = CultureInfo.InvariantCulture.Calendar;
if (configEntity.GroupsLastrun > now.AddDays(-1) && configEntity.Captureusersandgroups == "DAILY") continue;
if (configEntity.GroupsLastrun > cal.AddWeeks(now, -1) && configEntity.Captureusersandgroups == "WEEKLY") continue;
if (configEntity.GroupsLastrun > now.AddMonths(-1) && configEntity.Captureusersandgroups == "MONTHLY") continue;

或者只使用cal来处理所有事情:

代码语言:javascript
运行
复制
var now = DateTime.UtcNow; // See Jon Skeet's answer
var cal = CultureInfo.InvariantCulture.Calendar;
if (configEntity.GroupsLastrun > cal.AddDays(now, -1) && configEntity.Captureusersandgroups == "DAILY") continue;
if (configEntity.GroupsLastrun > cal.AddWeeks(now, -1) && configEntity.Captureusersandgroups == "WEEKLY") continue;
if (configEntity.GroupsLastrun > cal.AddMonths(now, -1) && configEntity.Captureusersandgroups == "MONTHLY") continue;
票数 3
EN

Stack Overflow用户

发布于 2013-04-10 14:16:05

作为另一种方法,您可以将运行周期存储在enum中,如下所示:

代码语言:javascript
运行
复制
enum RunPeriod
{
    Daily = 1,
    Weekly = 7,
    Monthly = 30
}

然后,您可以在数据库中存储int值,而不是string。这允许您在数据库端进行过滤,例如:

代码语言:javascript
运行
复制
var configsToRun = 
    from c in _myContext.Configs
    where EntityFunctions.AddDays(c.LastRun,(int)c.RunPeriod) > DateTime.Now);
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15917757

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档