【发布时间】:2010-12-23 05:14:42
【问题描述】:
我希望用户能够在程序中手动输入日期时间字段的格式。我有 Tedit 组件。例如,如果用户输入“HH:nn”,那么这是一个有效的日期时间格式字符串,并且所有日期时间组件都应将格式属性更改为此,但如果他输入“asd”,则不是。有没有一种快速的方法来检查这一点,而无需编写我自己的函数?
【问题讨论】:
标签: delphi string datetime datetime-format
我希望用户能够在程序中手动输入日期时间字段的格式。我有 Tedit 组件。例如,如果用户输入“HH:nn”,那么这是一个有效的日期时间格式字符串,并且所有日期时间组件都应将格式属性更改为此,但如果他输入“asd”,则不是。有没有一种快速的方法来检查这一点,而无需编写我自己的函数?
【问题讨论】:
标签: delphi string datetime datetime-format
您可以使用以下功能:
TryStrToDate
TryStrToTime
TryStrToDateTime
他们尝试将字符串转换为日期/时间,如果转换成功,则返回 true。所以没有引发异常。
您可以使用可选的 TFormatSettings 参数来定义自己的格式。
所有函数都在 SysUtils 中定义。
但是 VCL 中提供了一些日期/时间控件,例如 TDateTimePicker 和 TMonthCalendar。您也可以使用它们。
【讨论】:
问题是,您如何定义“有效格式”?可能,您能做的最好的事情就是在格式字符串中搜索特定字母的存在。但是如果用户不关心查看年份,或者不想查看时间怎么办?
我不会过分强调验证他们是否输入了“有效格式”。而是让他们预览他们使用当前日期时间输入的格式。
编辑:更新来自 OP 的新信息
对这个问题做了一点澄清:
实际上我需要在数据库中指定 TDateTimePicker 和 TDateTime 字段的 Format 属性。我希望用户能够更改这些格式。 ——托菲格·哈萨诺夫
这是一个重要的说明,也许您想将其包含在您的问题中?
重要的是格式字符串不仅会指示显示格式,还会指示编辑格式。现在,尽管几乎所有字符串都是有效的,但并非所有字符串都特别有用(尤其是对于编辑而言)。例如:
FDateTimeFormat := '"The day is "d" of this month of the year "yy';
这是完全有效的,因为您的日期可以进行相应的格式化。但是,它对于设置月份并不是特别有用。
现在恕我直言,如果用户想通过在其格式字符串中不包含月份字段来使他们的生活变得困难 - 很难!然而,问题在于格式规则有点技术性,用户可能会混淆数月和数分钟。例如。 FTimeFormat := 'HH:MM:SS' 实际上是
即便如此,我还是坚持我最初的建议(稍作调整):而只是让他们预览他们使用 当前日期时间 预定日期时间输入的格式应该强调格式字符串中的“错误”。
假设您有一个配置对话框,您打算让用户在其中定义此设置:
下面的代码应该可以解决问题:
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;
您提到您希望将其用于TDateTimeField 和TDateTimePicker。不幸的是,TDateTimePicker 只是封装了一个不使用 FormatDateTime 的内置 Windows 控件,因此它的格式字符串也有不同的规则。
所以恐怕您必须允许您的用户配置两种不同的格式字符串。 :(
【讨论】:
扩展 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;
【讨论】:
Doug 和 Gamecat,我相信你们都误解了这个问题。
DisplayDate := FormatDateTime(UserDefinedFormat, Now());
StrToDateTime(或 TryStrToDateTime)可以用于尝试循环“一致性检查”。但这并不好,因为不能保证用户想要查看日期/时间的所有元素。因此循环检查不起作用!
【讨论】:
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;
【讨论】:
过程 TForm1.BitBtn1Click(Sender: TObject);
变量
mydate,mydate1:TDateTime;
TestDate,TestDate1:string;
开始
测试日期:='13/15/2021';
TestDate1:='03/05/2021';
如果 IsValidDate(TestDate) 那么
开始
mydate:=strtodate(TestDate)
showmessage(TestDate+'是一个有效的日期');
结束
其他
showmessage(TestDate+' 不是有效日期!');
如果 IsValidDate(TestDate1) 那么
开始
mydate:=strtodate(TestDat1e)
showmessage(TestDate1+'是一个有效的日期');
结束
其他
showmessage(TestDate1+' 不是有效日期!');
结束;
函数 IsValidDate(S:string):boolean;
变量
FS:TFormatSettings;
DT:TDatetime;
开始
FS := TFormatSettings.Create('en-US');
如果 TryStrToDate(S,DT,FS) 那么
结果:=真
其他
结果:=假;
结束;
【讨论】: