我坚持使用一种奇怪的算法。看似简单实则不然。 用户可以以通配符格式给出任务执行日期。我应该在给定日期在低功耗嵌入式平台上执行任务。
有两种方法可以解决这个问题:
- 我的 MCU 可以每秒唤醒并检查当前日期是否与任何通配符日期匹配。如果是,则执行任务。该解决方案很简单,但由于每秒都要唤醒,所以会消耗大量电量。
- 其他解决方案可能是,如果我可以准确计算下一个任务执行日期,我可以安排我的嵌入式平台在预先计算的特定日期唤醒并在那时立即执行它。这将节省更多电量,因为整个平台在此期间将处于 sleep 模式。
我的问题始于计算下一个操作日期时间。
例如,给定的执行日期可以是:
FFFF/FF/FF FF:FF:FF
表示任意年/任意月/日任意小时/任意分钟/任意秒。我的意思只是每秒执行一次任务。FFFF/FF/FF FF:FF:00
表示该任务必须每分钟执行一次FFFF/FF/01 02:00:00
表示每个月的第一天 2 点2014/FF/15 FF:00:00
表示仅限 2014 年期间任何月份的 15 日的每个小时。FFFF/02/FF 00:00:00
表示二月的每一天午夜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/