Delphi 确认真实日期

Delphi 确认真实日期,delphi,delphi-xe2,Delphi,Delphi Xe2,是否有一些函数可以验证aaaa/mm/gg(ccyy/mm/dd)格式的日期,如果该日期有效,则返回True,否则返回False?我指的是真正有效的日期,而不仅仅是语法层面。是“aaaa”年和“gg”日吗 var MyString: string; MyDate: TDateTime; settings: TFormatSettings; begin settings.ShortDateFormat := 'yyyy/mm/dd'; settings.DateSeparato

是否有一些函数可以验证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;
函数IsValidDate(const S:string):布尔值;
变量
y、 m,d:整数;
常数
月的天数:整数=(31,29,31,30,31,30,31,31,30,31,30,31,30,
31, 30, 31);
开始
结果:=假;
如果长度为10,则退出;
如果是(S[5]'/')或(S[8]'/'),则退出;
如果不是TryStrToInt(复制(S,1,4),y),则退出;
如果不是TryStrToInt(复制(S,6,2),m),则退出;
如果不在范围(m,1,12)内,则退出;
如果不是TryStrToInt(复制(S,9,2),d),则退出;
如果不在范围内(d,1,月天数[m]),则退出;
如果(不是年(y))和(m=2)和(d=29),则退出;
结果:=真;
结束;

使用具有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位数的年份。将第二个测试更改为>=2表示两位数,但我只是认为强制执行四位数的年份并不是那么糟糕——只需再进行两次笔划

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

如果你想变得有趣,你可以检查一下这一年是否在过去10年内,或者是其他什么。只需添加:

Result := Result and (Now - TestDate < 3650);
Result:=结果和(现在-TestDate<3650);

戴夫

对不起,安德烈亚斯。:)这是可行的(因此没有否决票),但询问者使用的是XE2。更好的答案是@Arjen使用
t格式设置的答案。我会允许这个异常,而不是像Arjen那样使用
TryStrToDate
扔掉它。@Ken,谢谢。关于例外情况:取决于具体情况。Andreas,我没有投反对票。
strotdate(S,Format)
方法在某种程度上不是针对XE2的,但不够严格。肯定的。我认为real downvoter试图框定某人。注意:“如果S只包含两个数字,它将被解释为当前年份的日期(m/d或d/m)。”因此,可以使用格式不正确的字符串通过验证。而且,时间也会过去。此外,函数跳过前导空格,导致更多的误报。只指定设置记录的两个字段可能会很危险。我可能会首先尝试从当前活动的设置初始化它:设置:=TFormatSettings.Create(GetUserDefaultLCID);