我正在编写一个数据导入实用程序,以将数据导入数据库应用程序。可以从剪贴板(例如从Excel)或文件中检索数据,并且最初将其存储在TStringlist中。在下一步中,用户可以选择适当的列分隔符(制表符,逗号等)。将数据划分为列(使用选定的分隔符)后,将根据适用的数据库字段类型检查每个字符串值(我们称其为单元格值)的有效性。
我遇到的问题是日期时间值(可能还有日期和/或时间值,但是我还没有检查)。如果用户选择“错误的”分隔符,则不会拆分数据,并且每一行都包含一列(当然是正确的)。在这种情况下,单元格值可能包含类似于下面的字符串(在这种情况下,我正在显示调试值以显示正确的分隔符,制表符):
'04 / 01/10 00:00'#9'2.50'#9'100'#9'Text value'
使用TryStrToDateTime或StrToDatetime时,此字符串值“通过”,因为该字符串已“剪切”(即忽略尾随文本并返回正确的日期时间值04/01/10)。然后,如果我在稍后的阶段将单元格值(原始字符串)作为变体传递给范围比较函数,则它显然会失败,并出现EVariantTypeCastError。
是否存在一种方法(或现有的Delphi RTL函数)来检查字符串值,使其仅包含有效的日期(时间)(即无尾随文本)?无法找到考虑到这一点的函数(或函数参数),我也一直在考虑检查字符串长度,但是我的软件在国际上使用,因此datetime格式将有所不同,因此长度可能会有所不同。
PS:我在此处添加了以下示例代码,因为无法将其添加到评论中。
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;
答案 0 :(得分:0)
看来,解决方案(至少对于我的应用程序而言)是组合 TryStrToDateTime和TryStrToDate。为了演示,请启动一个新的VCL应用程序,并在窗体上放置一个ListBox和TButton(保留标准名称)。将以下代码粘贴到TButton OnClick处理程序中:
var
lDateVal, lDateTimeVal: TDateTime;
lStrVal: string;
lResult: boolean;
begin
ListBox1.Items.Clear;
lStrVal := '01/01/2019 10:00' + '-120.00' + '-Some text';
ListBox1.Items.Add('String value : ' + lStrVal);
lDateVal := EncodeDate(2000, 1, 1);
lDateTimeVal := EncodeDate(2000, 1, 1) + EncodeTime(1, 0, 0, 0);
lResult := TryStrToDate(lStrVal, lDateVal);
if lResult then
ListBox1.Items.Add(' - TryStrToDate : TRUE')
else
ListBox1.Items.Add(' - TryStrToDate : FALSE');
ListBox1.Items.Add('DateTime value: ' + DateTimeToStr(lDateVal));
lResult := TryStrToDateTime(lStrVal, lDateTimeVal);
if lResult then
ListBox1.Items.Add(' - TryStrToDateTime : TRUE')
else
ListBox1.Items.Add(' - TryStrToDateTime : FALSE');
ListBox1.Items.Add('DateTime value: ' + DateTimeToStr(lDateTimeVal));
// Reset
lDateVal := EncodeDate(2000, 1, 1);
lDateTimeVal := EncodeDate(2000, 1, 1) + EncodeTime(1, 0, 0, 0);
lResult := TryStrToDateTime(lStrVal, lDateTimeVal) and TryStrToDate(lStrVal, lDateVal);
if lResult then
ListBox1.Items.Add(' - Combined : TRUE')
else
ListBox1.Items.Add(' - Combined : FALSE');
ListBox1.Items.Add('DateTime value: ' + DateTimeToStr(lDateTimeVal));
ListBox1.Items.Add('');
lStrVal := '01/01/2019 10:00';
ListBox1.Items.Add('String value : ' + lStrVal);
lResult := TryStrToDateTime(lStrVal, lDateTimeVal) and TryStrToDate(lStrVal, lDateVal);
if lResult then
ListBox1.Items.Add(' - Combined : TRUE')
else
ListBox1.Items.Add(' - Combined : FALSE');
try
lDateTimeVal := VarToDateTime(lStrVal);
lResult := true;
except
lResult := false;
end;
if lResult then
ListBox1.Items.Add(' - Using Variant : TRUE')
else
ListBox1.Items.Add(' - Using Variant : FALSE');
这给我留下了一个问题,即与TryStrToDate相比,TryStrToDateTime是否实现不正确?至少,似乎在功能的“设计”上存在矛盾。 “字符串值是是一个日期”与“字符串值开始于一个DateTime”。除非我缺少什么...