根据日期和时间计算下一次运行任务的时间

2024-05-22

我有一个相当具体的问题,根据该任务的配置,找出计算程序中的“任务”下次运行时间的最佳方法。

从配置此“任务”的一些事物的定义开始。首先,一个看起来很像框架的枚举DayOfWeek枚举,我称之为DaysOfWeek并将其标记为FlagsAttribute表明它可以是其倍数:

[Flags]
public enum DaysOfWeek
{
    Sunday = 1,
    Monday = 2,
    Tuesday = 4,
    Wednesday = 8,
    Thursday = 16,
    Friday = 32,
    Saturday = 64
}

其次,具有适当属性的相关类以及我尝试实现的方法:

public class WeeklySchedule 
{

    public DaysOfWeek DaysToRun { get; set; }
    public TimeSpan TimeToRun{ get; set; }

    public override DateTime CalculateNextRunTime(DateTime lastRun)
    {
        // Here's what im trying to implement   
    }
}

要求应该很明显

  • 如果 DaysToRun 是今天,但 TimeToRun 今天已经过去,则返回下一个时间/天
  • 如果今天不包含在 DaysToRun 中,则查找下一天/时间来跑步

显然,我周一只是在放屁,因为我无法找到一种有效的方法来计算这个,缺少ShouldExecuteToday()方法,然后是FindNextExecutionDay()等等(也许这是正确的方法......)

Edit:好吧,周末的脑雾正在消散,这就是我到目前为止的情况。如果有人可以对此进行改进,我们将不胜感激:

首先,我将两个枚举的映射放入类的静态成员中,我知道我可以按照 @DorCohen 的示例从一个枚举到另一个枚举,但这让我感到恶心。

private static Dictionary<DayOfWeek, DaysOfWeek> DayToDaysMap 
 = new Dictionary<DayOfWeek, DaysOfWeek>()
{
{DayOfWeek.Monday, DaysOfWeek.Monday},
{DayOfWeek.Tuesday, DaysOfWeek.Tuesday},
{DayOfWeek.Wednesday, DaysOfWeek.Wednesday},
{DayOfWeek.Thursday, DaysOfWeek.Thursday},
{DayOfWeek.Friday, DaysOfWeek.Friday},
{DayOfWeek.Saturday, DaysOfWeek.Saturday},
{DayOfWeek.Sunday, DaysOfWeek.Sunday},
};

然后这个方法来确定是否应该在某一天运行:

private bool ShouldRunOn(DateTime now)
{
    var days = DayToDaysMap[now.DayOfWeek];
    // If the schedule is not set for the specified day, return false
    if (!this.DaysToRun.HasFlag(days))
        return false;

    // Schedule should run on specified day, just determine if it is in the past
    return this.TimeOfDay > now.TimeOfDay;    
}

那么实现就变成了; “我今天可以跑步吗”,如果不能的话,“提前 6 天,看看那天我是否可以跑步”。注意参数lastRun在此实现中未使用,它用于其他实现(例如重复计划)。

public override DateTime CalculateNextRunTime(DateTime lastRun)
{
    var now = DateTime.Now;
    if (ShouldRunOn(now))
        return new DateTime(now.Year,now.Month,now.Day,this.TimeOfDay.Hours,
              this.TimeOfDay.Minutes,this.TimeOfDay.Seconds);

    for (var i = 1; i < 7; i++)
    {
        now = now.AddDays(1).Date;
        if(ShouldRunOn(now))
            return new DateTime(now.Year, now.Month, now.Day, 
              this.TimeOfDay.Hours, this.TimeOfDay.Minutes, this.TimeOfDay.Seconds);
    }
    return DateTime.MinValue;
}

欢迎改进!


这是我的重写:

public DateTime CalculateNextRunTime()
{
    var now = DateTime.Now;
    for (var i = 0; i<=7; i++)
    {
        var potentialRunTime = now.AddDays(i);
        if (!DateInDayOfWeek(potentialRunTime))
            continue;
        potentialRunTime = potentialRunTime.Date + TimeToRun;
        if (potentialRunTime < DateTime.Now)
            continue;
        return potentialRunTime;
    }
    return DateTime.MinValue;
}

粗略的逻辑是:

从今天开始的每一天: - 检查当天是否有效,如果无效则跳至下一天 - 创建当天的运行时间 -检查运行时间是否是过去的,如果是跳到第二天,否则返回该运行时间。

对于第一个循环之后的所有循环来说,检查它是否是过去的时间显然是多余的,但对所有循环执行此操作会更简洁,而且我怀疑额外的比较可能会成为瓶颈。 :)

DateInDayOfWeek上面只是一个方法,如果过去的一天与保存在其中的一周中的某一天相匹配,则返回 trueDaysToRun财产。我无法使用 hasFlags,因为我在编写测试代码时没有使用 .NET 4。您可能希望将其保留为单独的方法,以避免它变得混乱。 ;-)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

根据日期和时间计算下一次运行任务的时间 的相关文章

随机推荐

  • 在Windows上安装smtplib的命令是什么

    我尝试使用以下命令在我的 Windows PC 上安装 smtplibpip and easy install但遇到以下错误 有人能告诉我如何在 Windows 上安装 smtplib 吗 C gt pip install smtplib
  • 以编程方式访问 Google App Engine 配额详细信息

    有谁知道是否可以通过 App Engine SDK 内的代码或某种形式的 WebAPI 访问您当前帐户配额的详细信息 我希望能够跟踪正在运行的应用程序中的数据存储使用情况和带宽使用情况 以便它可以根据应用程序剩余的配额级别来改变其行为 您可
  • Solr/Solrj 分页

    我正在创建的 Web 应用程序中使用 solr 和 solrj 来实现索引和搜索功能 我的请求处理程序在 solrconfig xml 中配置如下
  • lib.dom.ts 文件中最新的 typescript 重大更改

    在spec ts中例如 Dom spec ts describe matchesSelector gt let result boolean let matchelement HTMLElement it Matches for the o
  • Laravel 异常队列最大尝试次数超出

    我创建了一个应用程序来向多个用户发送电子邮件 但在处理大量收件人时遇到问题 该错误出现在failed jobs table Illuminate Queue MaxAttemptsExceededException App Jobs ESe
  • 导航栏隐藏在 SwiftUI 中不起作用

    我有三观 我想隐藏第三个视图中的导航栏 即使我给 navigationBarHidden true 导航栏正在显示 我找不到我哪里做错了 我已在下面附上我的代码和生成的屏幕截图 Xcode 版本 11 1 struct ContentVie
  • 在退出脚本之前等待后台进程完成

    在退出脚本 TCL Bash 之前 如何确保所有后台进程已完成执行 我正在考虑将所有后台进程 pid 写入 pid 文件 然后最后 pgrep pidfile 以查看在退出之前是否有任何进程仍在运行 有一些更简单的方法可以做到这一点吗 TC
  • NetBeans 将选项卡导航移至右侧

    我见过很少有人这样使用它 我正在努力思考 如何将 NetBeans IDE 中打开文件的导航移动到通过侧面的工具栏进行导航 换句话说 我希望选项卡显示在 NetBeans 的右侧 而不是在文件之间水平导航 就像在浏览器中一样 有人可以解释一
  • Apple AirLocation 演示应用程序测距不显示信标

    我有 3 个 Estimote 信标 可以通过 App store Estimate App 看到 现在我正在尝试运行 Apple 演示应用程序 AirLocation空中定位 https developer apple com libra
  • 如何在 Apache Camel 中定义通过 ref 抛出的异常

    必须在 XML 中定义的骆驼路由中抛出异常 成立throwExceptionCamel 2 3 中的声明如下所示
  • CakePHP hasOne/belongsTo 模型关系

    我有几个模型正在尝试关联 一种模型是Item 一个是Slide 另一个是Asset 项目下方有多个幻灯片 资产基本上是已上传的文件 图像 mp3 等 幻灯片是显示资产的位置 每张幻灯片都有一个资产 但给定的资产可能属于多张幻灯片 一张幻灯片
  • 如何在 Node JS 应用程序中顺序启动两个命令

    我使用 mocha chai 为我的 Node js 应用程序编写了一些单元测试 我想通过package json文件的scripts属性依次启动node JS服务器和测试套件 我的节点版本是6 9 4 我的 package json 中的
  • 如何在 Selenium for Python 上使用 XPATH 语法选择元素?

    考虑以下 HTML div div a class click abc a div div 我想单击 abc 但包装 div 可能会改变 所以 driver get element by xpath div id a div a class
  • sqlalchemy 插入或更新的简单方法?

    我有一系列新对象 它们看起来都类似于 Foo pk col1 x pk col2 y val bar 其中一些是存在的 Foo 即只有 val 与数据库中的行不同 并且应该生成更新查询 其他人应该生成插入 我可以想到几种方法来做到这一点 最
  • 如何创建包含多列MD5的GENERATED列?

    我尝试在 PostgreSQL 14 3 中添加下表 CREATE TABLE client cache id BIGINT PRIMARY KEY GENERATED ALWAYS AS IDENTITY request VARCHAR
  • 如何将我的 html 表单发布到 django 模型并保存?

    我有 html 表单 我想发送并保存到 django 模型 当我尝试发送消息时出现错误 ValueError at account userinfo akylson
  • 您可以在不是在 Google 协作平台下创建的网站上使用 Google 脚本吗? [复制]

    这个问题在这里已经有答案了 Google 脚本有一种方法可以嵌入到 Google 网站中 但我想知道是否可以在非 Google 托管的网站上使用 Google 脚本 此 google 脚本的目的是作为 Javascript 的简单替代方案
  • 具有独特矩阵转置问题的 2D 分块

    我有类型的复杂值数据struct complex double real 0 0 double imag 0 0 以 3 阶张量的形式组织 底层容器具有与内存页边界对齐的连续内存布局 The natural slicing directio
  • 通过缓存或委托调用提高性能?

    我正在尝试提高下面代码的性能 并且有点知道如何做 但不确定哪种方法是最好的方法 第一次点击会花费更长的时间 但后续点击应该会更快 现在 我可以缓存 T 其中 T 是一个类 然后检查缓存以查看 T 是否存在 如果存在 继续获取其相关信息 Na
  • 根据日期和时间计算下一次运行任务的时间

    我有一个相当具体的问题 根据该任务的配置 找出计算程序中的 任务 下次运行时间的最佳方法 从配置此 任务 的一些事物的定义开始 首先 一个看起来很像框架的枚举DayOfWeek枚举 我称之为DaysOfWeek并将其标记为FlagsAttr