我的应用程序上有一个第三方组件(FastReports)正在广泛使用System.Variants.VarToWideStr函数,这很好,只是它忽略了我需要该应用程序使用的区域设置。
示例:
FormatSettings.ShortDateFormat := 'dd/mm/yyyy';
ShowMessage(VarToWideStr(Date));
FormatSettings.ShortDateFormat := 'yyyy/mm/dd';
ShowMessage(VarToWideStr(Date));此代码始终返回相同的字符串,忽略我指示要使用的应用程序的区域设置。
您知道另一种方法来更改应用程序(具体地说是VarToWideStr)将要使用的区域设置吗?
发布于 2019-11-29 12:31:31
我认为你是被可怕的设计变体单位以及FastReport。VarToWideStr调用VarToWideStrDef,它调用隐式_VarToWStr,然后从单元System.VarUtils调用DateToWStrViaOS,最后调用VarBStrFromDate。
实际上,VarBStrFromDate是函数的引用,它的实现依赖于编译器。在Windows 32/64上,这只是oleaut32.dll对oleaut32.dll的引用。非Windows编译器返回到通过DateTimeToStr (单参数不变)转换值,后者使用全局格式设置和“c”格式说明符来格式化该值。
没有什么好办法来解决这个问题,因为所有这些例程都太依赖于全局状态。幸运的是(?)您可以将VarBStrFromDate指向您自己的实现。您可以从非Windows平台的默认实现中获得灵感,这种实现可以在单元BackupVarBStrFromDate的函数System.VarUtils中看到。然后你可以做这样的事情:
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, 11, 29, 10, 30, 50, 700)));为了得到结果:
2019-11-29 2019-11-29 10:30:50
您需要注意,这会改变整个应用程序中依赖VarBstrFromDate的所有例程的行为。
VarToStr也是如此。还请参见这里,其中作者建议在转换到字符串之前从变体中提取日期值。
https://stackoverflow.com/questions/59100960
复制相似问题