如何在Delphi中检查字符串是否是有效的DateTime格式字符串

时间:2009-12-04 11:40:16

标签: delphi string datetime datetime-format

我希望用户能够在程序中手动输入日期时间字段的格式。我有Tedit组件。例如,如果用户输入'HH:nn',那么这是一个有效的日期时间格式字符串,并且所有日期时间组件都应该将format属性更改为this,但如果他输入'asd',则不是。有没有快速的方法来检查这一点,而无需编写自己的函数?

6 个答案:

答案 0 :(得分:18)

您可以使用以下功能:

TryStrToDate
TryStrToTime
TryStrToDateTime

他们尝试将字符串转换为日期/时间,如果转换成功,则返回true。所以没有例外。

您可以使用可选的TFormatSettings参数来定义自己的格式。

所有功能都在SysUtils中定义。

但是VCL中有一些日期/时间控制可用,如TDateTimePicker和TMonthCalendar。你也可以使用它们。

答案 1 :(得分:4)

问题是,你如何定义'有效格式'?可能,您可以做的最好的事情是在格式字符串中搜索特定字母的存在。但是如果用户不关心看到年份,或者不想看时间呢?

我不会过分强调验证他们是否输入了“有效格式”。而只是让他们预览他们使用当前日期时间输入的格式。

修改:更新OP中的新信息

对这个问题有一点澄清:

  

实际上我需要在Database中指定TDateTimePicker和TDateTime字段的Format属性。我希望用户能够更改这些格式。 - Tofig Hasanov

这是一个重要的澄清,也许你想把它包含在你的问题中?

重要的是格式字符串不仅会指示显示格式,还会指示编辑格式。现在虽然几乎任何字符串都是有效的,但并非所有字符串都特别有用(特别是对于编辑)。 E.g:

FDateTimeFormat := '"The day is "d" of this month of the year "yy';

这是完全有效的,因为您的日期可以相应地格式化。但是,它对设置月份并不是特别有用。

现在恕我直言,如果用户想要通过不在其格式字符串中包含月份字段来使他们的生活变得困难 - 很难!然而问题在于格式规则有点技术性,用户可能会混淆几个月和几分钟。例如。 FTimeFormat := 'HH:MM:SS'实际上是< hours>:< >:< seconds>

即便如此,我仍然支持我的原始建议(只需一个小调整):而是让他们使用当前日期时间预定日期时间预览他们输入的格式这应该强调格式字符串中的“错误”。

假设您有一个配置对话框,您希望让用户定义此设置:

  • 添加一个TComboBox(然后您可以使用示例字符串'预加载'来引导用户;他们也可以选择一个已经合适的选项。
  • 添加一个标签,在其中说明所选格式字符串的示例行为。
  • 实现TComboBox.OnChange以说明用户选择的效果。

以下代码可以解决这个问题:

procedure TConfigDialog.DateTimeFormatChange(Sender: TObject);
var
  LCheckDate: TDateTime;
  LFormattedDate: String;
begin
  LCheckDate := EncodeDate(1999, 12, 31) + EncodeTime(20, 45, 50, 123);
  LFormattedDate := FormatDateTime(DateTimeFormat.Text, LCheckDate);
  DateFormatSample.Caption := 'Fri 31 December 1999 at 8:45:50.123 would be displayed as: ' + LFormattedDate;
end;

警告

您提到要对TDateTimeFieldTDateTimePicker使用此功能。不幸的是,TDateTimePicker只包含一个不使用FormatDateTime的内置Windows Control,因此对其格式字符串也有不同的规则。

所以我担心你必须允许你的用户配置两个不同的格式字符串。 :(

答案 2 :(得分:1)

扩展Gamecat的答案

If not tryStrToDateTime(Edit1.text,MyDateTimeVar) then
ShowMessage('You need to make your entry look like a date...how about yy/mm/dd');

如果您只想检查它而不设置MyDateTimeVar变量以传递给tryStrToDateTimeVar,您可以使用异常处理

try
StrToDateTime(Edit1.Text);
except
ShowMessage('You need to make your entry look like a date...how about yy/mm/dd');
end;

答案 3 :(得分:1)

Doug和Gamecat,我相信你们都误解了这个问题。

  • 他不想从字符串到日期。
  • 他有约会。
  • 他希望根据用户指定的格式将该日期转换为字符串。
  • 即。 DisplayDate := FormatDateTime(UserDefinedFormat, Now());

StrToDateTime(或TryStrToDateTime)唯一可以用于尝试循环'一致性检查'。但这并不好,因为无法保证用户想要查看日期/时间的所有元素。因此,循环检查不起作用!

答案 4 :(得分:0)

function to_date(p_format,p_string:string): TDateTime;
var
  v_day,           //dd
  v_month,         //mm
  v_year:Integer;  //yyyy
  v_hour,          //hh
  v_minute,        //nn
  v_second:Integer;//ss

  v_date:TDateTime;
  v_time:TDateTime;
begin
  v_day:=Pos('dd',p_format);
  v_month:=Pos('mm',p_format);
  v_year:=Pos('yyyy',p_format);

  v_hour:=Pos('hh',p_format);
  v_minute:=Pos('nn',p_format);
  v_second:=Pos('ss',p_format);

  v_day:=StrToInt(Copy(p_string,v_day,2));
  v_month:=StrToInt(Copy(p_string,v_month,2));
  v_year:=StrToInt(Copy(p_string,v_year,4));

  v_hour:=StrToInt(Copy(p_string,v_hour,2));
  v_minute:=StrToInt(Copy(p_string,v_minute,2));
  v_second:=StrToInt(Copy(p_string,v_second,2));

  v_date:=EncodeDate(v_year,v_month,v_day);
  v_time:=EncodeTime(v_hour,v_minute,v_second,0);
  ReplaceTime(v_date,v_time);
  Result:=v_date;
end;

答案 5 :(得分:0)

程序 TForm1.BitBtn1Click(Sender: TObject);
变量
mydate,mydate1:TDateTime;
TestDate,TestDate1:string;
开始
测试日期:='13/15/2021';
TestDate1:='03/05/2021';

if IsValidDate(TestDate) then
开始
mydate:=strtodate(TestDate)
showmessage(TestDate+' is a valid date');
结束
其他
showmessage(TestDate+' 不是有效日期 !');

if IsValidDate(TestDate1) then
开始
mydate:=strtodate(TestDat1e)
showmessage(TestDate1+' is a valid date');
结束
其他
showmessage(TestDate1+' 不是有效日期 !');

结束;

函数 IsValidDate(S:string):boolean;
变量
FS:TFormatSettings;
DT:日期时间;
开始
FS := TFormatSettings.Create('en-US');

如果 TryStrToDate(S,DT,FS) 那么
结果:=真
其他
结果:=假;

结束;