string 如何在 Delphi 中检查字符串是否是有效的日期时间格式字符串
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1846446/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to check if string is a valid DateTime Format string in Delphi
提问by Tofig Hasanov
I want user to be able to manually enter format of the datetime fields in the program. I have Tedit component. For example if user enters 'HH:nn', then this is a valid datetime format string and all datetime components should change format property to this, but if he enters 'asd', it is not. Is there a quick way to check this, without writing my own function?
我希望用户能够在程序中手动输入日期时间字段的格式。我有 Tedit 组件。例如,如果用户输入“HH:nn”,则这是一个有效的日期时间格式字符串,所有日期时间组件都应将格式属性更改为此,但如果他输入“asd”,则不是。有没有一种快速的方法来检查这个,而无需编写我自己的函数?
回答by Toon Krijthe
You could use the functions:
您可以使用以下功能:
TryStrToDate
TryStrToTime
TryStrToDateTime
They try to convert a string to a date/time and if the conversion succeeds, it returns true. So there are no exceptions raised.
他们尝试将字符串转换为日期/时间,如果转换成功,则返回 true。所以没有例外。
You can use the optional TFormatSettings parameter to define your own format.
您可以使用可选的 TFormatSettings 参数来定义您自己的格式。
All functions are defined in SysUtils.
所有函数都在 SysUtils 中定义。
But there are some date/time controls available in the VCL like TDateTimePicker and TMonthCalendar. You can use them also.
但是在 VCL 中有一些可用的日期/时间控件,如 TDateTimePicker 和 TMonthCalendar。您也可以使用它们。
回答by Disillusioned
The problem is, how do you define a 'valid format'? Possibly, the best you could do is search for the existence of specific letters in the format string. But what if the user doesn't care about seeing the year, or doesn't want to see the time?
问题是,您如何定义“有效格式”?可能,您能做的最好的事情就是在格式字符串中搜索特定字母的存在。但是如果用户不关心看到年份,或者不想看到时间怎么办?
I wouldn't stress too much about verifying that they have entered a 'valid format'. Rather just give them a preview of the format they've entered using the current date-time.
我不会过多强调验证他们是否输入了“有效格式”。而只是让他们预览他们使用当前日期时间输入的格式。
Edit: Update for new info from OP
编辑:更新来自 OP 的新信息
There was a little clarification on the question:
关于这个问题有一点澄清:
Actually I need to specify Format property of TDateTimePicker and TDateTime fields in Database. And I want user to be able to change these formats. – Tofig Hasanov
实际上我需要在数据库中指定 TDateTimePicker 和 TDateTime 字段的格式属性。我希望用户能够更改这些格式。– 托菲格哈萨诺夫
That's an important clarification, perhaps you want to include it in your question?
这是一个重要的澄清,也许您想将其包含在您的问题中?
The important thing is that the format string will not only indicate the Display Format, but also the editing format. Now although pretty much any string is valid, not all are particularly useful (especially for editing). E.g.:
重要的是,格式字符串不仅会指示显示格式,还会指示编辑格式。现在,尽管几乎所有字符串都是有效的,但并非所有字符串都特别有用(尤其是对于编辑)。例如:
FDateTimeFormat := '"The day is "d" of this month of the year "yy';
This is perfectly valid in the sense that your date can beformatted accordingly. However, it is not particularly useful for setting the month.
这是完全有效的,因为您的日期可以相应地格式化。但是,它对于设置月份并不是特别有用。
Now IMHO, if a user wants to make make their lives difficult by not including month fields in their format string - tough! The problem however comes in that the format rules are a little technical, and a user may get months and minutes mixed up. E.g. FTimeFormat := 'HH:MM:SS'
which is actually <hours>:<months>:<seconds>
现在恕我直言,如果用户想通过在格式字符串中不包含月份字段来使他们的生活变得困难 - 很难!然而,问题在于格式规则有点技术性,用户可能会混淆几个月和几分钟。例如FTimeFormat := 'HH:MM:SS'
,实际上是 <hours>:< months>:<seconds>
Even so, I stand by my original suggestion (with one minor tweak): Rather just give them a preview of the format they've entered using the current date-timea predetermined date-time that should emphasise 'mistakes' in the format string.
即便如此,我仍然坚持我最初的建议(稍作调整):而只是让他们预览他们使用当前日期时间输入的格式,这是一个预先确定的日期时间,应该强调格式字符串中的“错误” .
Assuming you have a configuration dialog in which you intend letting the user define this setting:
假设您有一个配置对话框,您打算让用户在其中定义此设置:
- Add a TComboBox (you can then 'pre-load' it with sample strings to guide the user; also they may simply choose one of your already suitable options.
- Add a label in which you illustrate the sample behaviour of the chosen format string.
- Implement TComboBox.OnChange to illustrate the effect of the user's choice.
- 添加一个 TComboBox(然后您可以使用示例字符串“预加载”它以指导用户;他们也可以简单地选择您已经合适的选项之一。
- 添加一个标签,您可以在其中说明所选格式字符串的示例行为。
- 实现 TComboBox.OnChange 来说明用户选择的效果。
The following code should do the trick:
以下代码应该可以解决问题:
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;
WARNING
警告
You mentioned you want to use this for both TDateTimeField
and TDateTimePicker
. Unfortunately, TDateTimePicker
simply wraps a built-in Windows Control which does not use FormatDateTime, and consequently also has different rules for its format strings.
你提到你想将它用于TDateTimeField
和TDateTimePicker
。不幸的是,TDateTimePicker
简单地包装了一个不使用 FormatDateTime 的内置 Windows 控件,因此对其格式字符串也有不同的规则。
So I'm afraid you'll have to allow your users to configure two different format strings. :(
所以恐怕您必须允许您的用户配置两种不同的格式字符串。:(
回答by Doug Johnson-Cookloose
To expand on Gamecat's answer
扩展Gamecat的答案
If not tryStrToDateTime(Edit1.text,MyDateTimeVar) then
ShowMessage('You need to make your entry look like a date...how about yy/mm/dd');
If you just want to check it without setting up the MyDateTimeVar variable to pass to tryStrToDateTimeVar you can just use exception handling
如果您只想检查它而不设置 MyDateTimeVar 变量以传递给 tryStrToDateTimeVar 您可以只使用异常处理
try
StrToDateTime(Edit1.Text);
except
ShowMessage('You need to make your entry look like a date...how about yy/mm/dd');
end;
回答by Disillusioned
Doug and Gamecat, I believe you are both misunderstanding the question.
Doug 和 Gamecat,我相信你们都误解了这个问题。
- He doesn't want to go from a string to a date.
- He has the date.
- He wants to convert that date into a string according to a format specified by the user.
- I.e.
DisplayDate := FormatDateTime(UserDefinedFormat, Now());
- 他不想从字符串变成日期。
- 他有约会。
- 他想根据用户指定的格式将该日期转换为字符串。
- IE
DisplayDate := FormatDateTime(UserDefinedFormat, Now());
The only thing that StrToDateTime (or TryStrToDateTime) couldbe used for is to attempta circular 'consistency check'. But that would be no good, because there is no guarantee the user wants to see all elements of the date/time. Consequently the circular check cannot work!
该StrToDateTime(或TryStrToDateTime)唯一可以被用于对企图圆形“一致性检查”。但这并不好,因为不能保证用户想要查看日期/时间的所有元素。因此循环检查不起作用!
回答by hajili
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;