首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >更改Sysem.Variants.VarToWideStr的区域设置格式

更改Sysem.Variants.VarToWideStr的区域设置格式
EN

Stack Overflow用户
提问于 2019-11-29 08:06:53
回答 1查看 1K关注 0票数 2

我的应用程序上有一个第三方组件(FastReports)正在广泛使用System.Variants.VarToWideStr函数,这很好,只是它忽略了我需要该应用程序使用的区域设置。

示例:

代码语言:javascript
复制
FormatSettings.ShortDateFormat := 'dd/mm/yyyy';
ShowMessage(VarToWideStr(Date));
FormatSettings.ShortDateFormat := 'yyyy/mm/dd';
ShowMessage(VarToWideStr(Date));

此代码始终返回相同的字符串,忽略我指示要使用的应用程序的区域设置。

您知道另一种方法来更改应用程序(具体地说是VarToWideStr)将要使用的区域设置吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-11-29 12:31:31

我认为你是被可怕的设计变体单位以及FastReport。VarToWideStr调用VarToWideStrDef,它调用隐式_VarToWStr,然后从单元System.VarUtils调用DateToWStrViaOS,最后调用VarBStrFromDate

实际上,VarBStrFromDate是函数的引用,它的实现依赖于编译器。在Windows 32/64上,这只是oleaut32.dlloleaut32.dll的引用。非Windows编译器返回到通过DateTimeToStr (单参数不变)转换值,后者使用全局格式设置和“c”格式说明符来格式化该值。

没有什么好办法来解决这个问题,因为所有这些例程都太依赖于全局状态。幸运的是(?)您可以将VarBStrFromDate指向您自己的实现。您可以从非Windows平台的默认实现中获得灵感,这种实现可以在单元BackupVarBStrFromDate的函数System.VarUtils中看到。然后你可以做这样的事情:

代码语言:javascript
复制
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也是如此。还请参见这里,其中作者建议在转换到字符串之前从变体中提取日期值。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59100960

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档