日付を含んでいるバリアントに対し VarToStrを使用すると、SysUtils.ShortDateFormatで設定した形式を使用するのではなく、OSの日付の設定を使用してしまう

概要: 日付を含んでいるバリアントに対し VarToStrを使用すると、SysUtils.ShortDateFormatで設定した形式を使用するのではなく、OSの日付の設定を使用してしまう問題に関して説明します。

Product Name:        Delphi
Product Version:      2006, 2007, 2009, 2010
Product Component:    Compiler
Platform/OS version:  Win32

    問題点

日付を含んでいるバリアントに対し VarToStrを使用すると、SysUtils.ShortDateFormatで設定した形式を使用するのではなく、OSの日付の設定を使用してしまいます。

    対応方法

この問題の原因は、Variantユニットの内部の深いところにあります。VarToStrは、OSの API関数を呼出して、ユーザーのデフォルトロケールを使用するようハードコードされている点にあります。

この問題は、バリアントから加工していない日付データを取り出すという簡単な方法で回避できます。

var
  DateVariant: Variant;
begin
  Application.UpdateFormatSettings := False;
  SysUtils.ShortDateFormat := ‘dd#MM#yyyy’:  // uses a strange shortdateformat string
  ShowMessage(dateToStr(Date));
  // Image this variant is being pulled out from a database
  DateVariant := Date;
  ShowMessage(VarToStr(DateVariant));  // this will show the date using the OS date setting
  ShowMessage(DateToStr(TVarData(DateVariant).VDate));  // using some casting th issue can be resolved.
end;