确认一个真实的约会



是否有一些函数可以验证格式aaaa/mm/gg (ccyy/mm/dd)返回True的日期,如果它有效或False否则?我指的是真正有效的日期,而不仅仅是语法层面。

'aaaa'是年'gg'是日?

var
  MyString: string;
  MyDate: TDateTime;
  settings: TFormatSettings;
begin
  settings.ShortDateFormat := 'yyyy/mm/dd';
  settings.DateSeparator := '/';
  MyString := '2011/15/15';
  if TryStrToDateTime(MyString, MyDate, settings) then
    Label1.Caption := 'correct date'
  else
    Label1.Caption := 'incorrect';
end;

这是非常快的,因为最简单的错误首先被捕获。

function IsValidDate(const S: string): boolean;
var
  y, m, d: Integer;
const
  DAYS_OF_MONTH: array[1..12] of integer = (31, 29, 31, 30, 31, 30, 31, 31, 30,
  31, 30, 31);
begin
  result := false;
  if length(S) <> 10 then Exit;
  if (S[5] <> '/') or (S[8] <> '/') then Exit;
  if not TryStrToInt(Copy(S, 1, 4), y) then Exit;
  if not TryStrToInt(Copy(S, 6, 2), m) then Exit;
  if not InRange(m, 1, 12) then Exit;
  if not TryStrToInt(Copy(S, 9, 2), d) then Exit;
  if not InRange(d, 1, DAYS_OF_MONTH[m]) then Exit;
  if (not IsLeapYear(y)) and (m = 2) and (d = 29) then Exit;
  result := true;
end;

使用带有TFormatSettings参数的StrToDate()的重载版本。然后,您可以传入所需的格式字符串进行解析,它将在验证已解析的值后返回TDateTime。

尝试做同样的事情,并跑过这个旧线程。我最终写了自己的函数,并想把它贴出来。这个怎么样?

function IsValidDate(const S: string): boolean;
 var TestDate : tdatetime;
begin
 Result := False;
 if (LastDelimiter('/',S) >= 4) 
 and 
 (Length(S)-LastDelimiter('/',S) >= 4) 
 then
  Result := TryStrToDate(S,TestDate);
 end;

首先,我检查第二个分隔符(/)是否至少足够远,可以同时表示一天和一个月(第4个位置)。然后我用下一行对他们强制使用4位数的年份。对于两位数字,将第二个测试更改为>=2,但我只是认为强制使用四位数字年份并不是那么糟糕-它只是多了两个笔划。

最后,我使用TryStrToDate()进行测试。如果只有一个分隔符,或者它不是一个有效的日期,它将在这里被捕获。

如果你想更花哨一点,你可以检查一下这一年是否在过去的10年之内。只需添加:

Result := Result and (Now - TestDate < 3650);
戴夫

最新更新