我认为您对Variants单元和FastReport的糟糕设计感到困惑。 VarToWideStr
调用VarToWideStrDef
,这会先调用隐式_VarToWStr
,然后再调用DateToWStrViaOS
,最后再从单元VarBStrFromDate
调用System.VarUtils
。
实际上VarBStrFromDate
是对函数的引用,其实现取决于编译器。在Windows 32/64上,这只是对oleaut32.dll
中VarBstrFromDate的引用。非Windows编译器会退回到通过使用全局格式设置和'C' format specifier格式化值的DateTimeToStr
(单参数不变)来转换值。
没有办法解决这个问题,因为所有这些例程都过于依赖全局状态。幸运的是,您可以将VarBStrFromDate
指向您自己的实现。在单元BackupVarBStrFromDate
的功能System.VarUtils
中可以看到非Windows平台默认实现的启发。然后您可以执行以下操作:
uses
System.SysUtils,System.Variants,System.VarUtils,System.DateUtils;
function MyVarBstrFromDate(dateIn: TDateTime; LCID: Integer; dwFlags: Integer;
out bstrOut: WideString): HRESULT; stdcall;
begin
if LCID = VAR_LOCALE_USER_DEFAULT then
begin
bstrOut := DateTimeToStr(dateIn);
Result := VAR_OK;
end
else
Result := VAR_NOTIMPL;
end;
{ ... }
System.VarUtils.VarBstrFromDate := MyVarBstrFromDate;
FormatSettings.ShortDateFormat := 'yyyy-mm-dd';
FormatSettings.LongTimeFormat := 'hh:nn:ss';
Writeln(VarToWideStr(EncodeDate(2019,11,29)));
Writeln(VarToWideStr(EncodeDateTime(2019,29,10,30,50,700)));
获得结果:
2019-11-29
2019-11-29 10:30:50
您需要注意,这会改变整个应用程序中依赖于VarBstrFromDate
的所有例程的行为。
VarToStr
也是如此。另请参见here,作者建议在转换为字符串之前先从变量中提取日期值。
本文链接:https://www.f2er.com/3009139.html