c++ - 使用通配符计算下一个最近的日期时间匹配

标签 c++ c algorithm delphi

我坚持使用一种奇怪的算法。看似简单实则不然。 用户可以以通配符格式给出任务执行日期。我应该在给定日期在低功耗嵌入式平台上执行任务。

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

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

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

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

  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

示例可以增加,但我相信我已经解释了问题。

我需要一个算法,它将当前日期作为第一个参数,用户通配符日期作为第二个参数,它应该计算并返回下一个执行日期。应在不使用 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;

正如我之前指出的,我需要一个无循环且及时确定的解决方案。

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

谢谢。

最佳答案

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

它允许定期安排作业,或基于带有通配符的特定时间安排作业。

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

无需轮询,只需添加定时逻辑字符串和要调用的事件即可。

关于c++ - 使用通配符计算下一个最近的日期时间匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23309783/

相关文章:

php - 提取知识图谱数据结构之间的联系

c++ - 邻接表函数中的段错误

c - 列出目录中的文件并在 C/C++ 中删除它们

c++ - 如何将库合并到我的可执行文件中,以便用户不需要拥有 DLL?

objective-c - 将 CFIndex 转换为 NSUInteger?

c - 分割数组中的数字

swift - 如何使用 Swift 检测链表中的循环/周期

c - Haskell二叉树快速实现

android - 蓝牙串口通讯,HC-06模块转安卓手机

c++ - TCP 和 UDP 干扰