【发布时间】:2019-02-03 11:09:50
【问题描述】:
我正在编写一个数据导入实用程序来将数据导入数据库应用程序。可以从剪贴板(例如从 Excel)或文件中检索数据,并且最初存储在 TStringlist 中。在下一步中,用户可以选择适当的列分隔符(制表符、逗号等)。将数据拆分为列后(使用选定的分隔符),每个字符串值(我们称之为单元格值)都会根据适用的数据库字段类型检查有效性。
我遇到的问题是日期时间值(可能还有日期和/或时间值,但我还没有检查过)。如果用户选择了“错误”的分隔符,则数据不会被拆分,并且每一行都包含一列(当然这是正确的)。在这种情况下,单元格值可能包含如下所示的字符串(我正在显示调试值以显示正确的分隔符,在这种情况下为制表符):
'04/01/10 00:00'#9'2.50'#9'100'#9'文本值'
当使用 TryStrToDateTime 或 StrToDatetime 时,该字符串值“通过”,因为字符串被“剪裁”(即忽略尾随文本并返回正确的日期时间值 04/01/10)。如果我在稍后阶段将单元格值(原始字符串)作为变量传递给范围比较函数,它显然会因 EVariantTypeCastError 而失败。
是否有方法(或现有的 Delphi RTL 函数)来检查字符串值是否仅包含有效的日期(时间)(即没有尾随文本)?考虑到这一点,找不到函数(或函数参数),我也一直在考虑检查字符串长度,但我的软件在国际上使用,因此日期时间格式会有所不同,因此可能有不同的长度。
PS:我在这里添加了下面的示例代码,因为我无法将它添加到我的 cmets。
procedure TForm1.Button1Click(Sender: TObject);
var
lStrVal: string;
lIsDateTime: boolean;
lDateTimeVal: TDateTime;
begin
lStrVal := '01/01/2019 10:00' + chr(9) + '120.00' + chr(9) + 'Some text';
lIsDateTime := TryStrToDateTime(lStrVal, lDateTimeVal);
if lIsDateTime then
messageDlg('String value is a date/time! ' + #13#10 + 'String: ' + lStrVal + #13#10 + 'Date/time is: ' + DateTimeToStr(lDateTimeVal), mtInformation, [mbOK], 0)
else
messageDlg('String value cannot be converted to a date/time!', mtWarning, [mbOK], 0);
end;
【问题讨论】:
-
您似乎忽略了
TryStrToDateTime()的返回值(布尔值),因为它使用您的测试字符串返回False,尽管TDateTime值可能是正确的。因此,您也不会检测到真正的日期时间错误。但是,如果您对此感到满意,那么您也拥有您所要求的功能。只需将您获得的日期时间转换回字符串,以便去除原始字符串中日期时间之后的任何垃圾? -
@TomBrunberg;其实我并没有忽略返回值。请考虑我添加到问题中的代码。您必须相信我的话,返回值为“真”。
-
那么,也许Delphi版本有区别。我用的是XE7,你用的是什么?
-
德尔福 10.3 Rio。您是说该函数在 XE7 中正常工作(即返回 false)吗?
-
@TomBrunberg,由于某些原因,尾随字符被忽略。您看到的是日期时间格式不适合您的语言环境设置。只需输入一个有效的日期时间字符串,后跟一些额外的不相关字符,该函数将返回 true。
标签: string validation datetime delphi