计算下一个最近的日期时间与通配符匹配

时间:2014-04-26 10:49:06

标签: c++ c algorithm delphi

我坚持使用一种奇怪的算法。看起来很简单但不是。 用户可以以野外格式提供任务执行日期。我应该在低功耗嵌入式平台上执行任务。

有两种方法可以解决问题:

  • 我的MCU可以每秒唤醒并检查当前日期是否与任何通配日期匹配。如果是,则执行任务。这种解决方案很简单,但每秒钟都会消耗掉大量的电力。
  • 其他解决方案可能是,如果我可以准确计算下一个任务执行日期,我可以安排我的嵌入式平台在预先计算的特定日期醒来并在那时立即执行。这将节省更多电量,因为在此期间整个平台将处于睡眠模式。

我的问题始于计算下一个行动日期时间。

例如,给定的执行日期可以是:

  1. FFFF/FF/FF FF:FF:FF表示任何年/任何月/日任何小时/任何分钟/任何秒数。我的意思就是执行任务一秒钟。
  2. FFFF/FF/FF FF:FF:00表示该任务必须每分钟执行一次
  3. FFFF/FF/01 02:00:00表示每月的第一天2点
  4. 2014/FF/15 FF:00:00表示仅在2014年的任何月份的第15天的每个小时。
  5. FFFF/02/FF 00:00:00表示二月的每一天午夜
  6. FFFF/01/01 04:30:00表示每年4:30开始
  7. 可以增长例子,但我相信我解释了这个问题。

    我需要一个算法,它将当前日期作为第一个参数,用户通配日期作为第二个参数,它应该计算并返回下一个执行日期。应该在不使用while循环的情况下计算任务的下一个执行时间。 (因为它必须在时间上快速且确定)

    对于那些不知道我做了什么的人(不幸的是,while循环几乎就像几秒钟一样醒来):

    作为算法:

    1: Increment Current Date by a second
    2: Check if it matches with wildcarded pattern
    3: Goto 1 if it is not matching.
    
    德尔福的

    function DoesDateMatchWithPattern(const pattern: string; const dt: TDateTime): Boolean;
    Var
      year, month, day,
      hour, minute, second,
      ms: Word;
    
      syear, smonth, sday,
      shour, sminute, ssecond : String;
    
    begin
      Result := True;
      DecodeDateTime(dt, year, month, day, hour, minute, second, ms);
    
      // decode patten items
      // 1    6  9  C  F
      // FFFF/FF/FF FF:FF:FF
      syear :=    Copy(pattern, 1, 4);
      smonth :=   Copy(pattern, 6, 2);
      sday :=     Copy(pattern, 9, 2);
      shour :=    Copy(pattern, 12, 2);
      sminute :=  Copy(pattern, 15, 2);
      ssecond :=  Copy(pattern, 18, 2);
    
      // any non wildcarded sections have to match, otherwise returns false
      if (syear <> 'FFFF') and (StrToInt(syear) <> year) then
        Result := False;
    
      if (smonth <> 'FF') and (StrToInt(smonth) <> month) then
        Result := False;
    
      if (sday <> 'FF') and (StrToInt(sday) <> day) then
        Result := False;
    
      if (shour <> 'FF') and (StrToInt(shour) <> hour) then
        Result := False;
    
      if (sminute <> 'FF') and (StrToInt(sminute) <> minute) then
        Result := False;
    
      if (ssecond <> 'FF') and (StrToInt(ssecond) <> second) then
        Result := False;
    end;
    
    function CalculateNextDateTime(const pattern: string; out next_date_to_execute: TDateTime): Boolean;
    var
      last_possible_date : TDateTime;
    
    begin
      Result := false;
    
      last_possible_date := EncodeDate(2099, 12, 31);
    
      // takes current date time
      next_date_to_execute := Now();
    
      while (next_date_to_execute <= last_possible_date) and (not Result) do
      begin
        // calculate next second
        next_date_to_execute := IncSecond(next_date_to_execute);
    
        // check if it matches with the pattern given
        Result := DoesDateMatchWithPattern(pattern, next_date_to_execute);
      end;
    end;
    

    正如我之前所说,我需要一个无循环且确定性的解决方案。

    任何关于伪算法或问题名称的建议 - 我可以搜索它 - 或任何想法都被接受。

    谢谢。

1 个答案:

答案 0 :(得分:2)

我相信你正在寻找一个CRON调度程序,请参阅wiki信息:cron

它允许按时间间隔安排作业,或者根据具有通配符的特定时间安排作业。

您可以在另一个SO问题Looking for an event scheduler for Delphi?中找到实现此逻辑的Delphi组件。

不需要轮询,只需添加一个定时逻辑字符串和一个要调用的事件。