我坚持使用一种奇怪的算法。看起来很简单但不是。 用户可以以野外格式提供任务执行日期。我应该在低功耗嵌入式平台上执行任务。
有两种方法可以解决问题:
我的问题始于计算下一个行动日期时间。
例如,给定的执行日期可以是:
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;
正如我之前所说,我需要一个无循环且确定性的解决方案。
任何关于伪算法或问题名称的建议 - 我可以搜索它 - 或任何想法都被接受。
谢谢。
答案 0 :(得分:2)
我相信你正在寻找一个CRON调度程序,请参阅wiki信息:cron。
它允许按时间间隔安排作业,或者根据具有通配符的特定时间安排作业。
您可以在另一个SO问题Looking for an event scheduler for Delphi?中找到实现此逻辑的Delphi组件。
不需要轮询,只需添加一个定时逻辑字符串和一个要调用的事件。