0

Delphi には次の機能があります。

function VarToDateAsString(const V: TVarData): TDateTime;
....
LResult := VarDateFromStr(S, VAR_LOCALE_USER_DEFAULT, 0, Result);

今日の日付でこれを行う:

   VarDateFromStr('07;12;18', VAR_LOCALE_USER_DEFAULT, 0, Result);

結果は等しくなります

Result = '07;18;12'

修正は可能ですか?

コード例

procedure TForm1.Button1Click(Sender: TObject);
var
  LDateTimeVar: Variant;
  LDateTime: TDateTime;
begin
  // Current date separator in OS settings is ';'
  LDateTimeVar := '07;12;18';
  LDateTime := VarToDateTime(LDateTimeVar);
  // Expected LDateTime = '07;12;18', 
  // but will be LDateTime = '07;18;12'  
  ShowMessage(DateToStr(LDateTime));
end;
4

1 に答える 1

2

VarToDateAsString'oleaut32'sVarDateFromStrを呼び出して変換を実行しますが、年が真ん中にある場合は単純に失敗します。

variants.VarToDateAsString:

function VarToDateAsString(const V: TVarData): TDateTime;
var
  ...
begin
  _VarToWStr(S, V);
  LResult := VarDateFromStr(S, VAR_LOCALE_USER_DEFAULT, 0, Result);
  ...

Result2 行目にブレークポイントを配置すると、パラメーターが日と年を逆にすることがわかります。を呼び出して、自分でテストを実行できますactivex.VarDateFromStr

variants.VarToDateAsString呼び出しをバイパスして独自の関数を実装することはできますが、中年の形式もサポートしていないため、VarDateFromStr何かを使用することは考えないでください。を呼び出し、次に を呼び出します。以下は関数全体です。sysutilssysutils.TryStrToDateTimeScanDateGetDateOrder

function GetDateOrder(const DateFormat: string): TDateOrder;
var
  I: Integer;
begin
  Result := doMDY;
  I := 1;
  while I <= Length(DateFormat) do
  begin
    case Chr(Ord(DateFormat[I]) and $DF) of
      'E': Result := doYMD;
      'Y': Result := doYMD;
      'M': Result := doMDY;
      'D': Result := doDMY;
    else
      Inc(I);
      Continue;
    end;
    Exit;
  end;
end;

ご覧のとおり、年が真ん中にある結果の順序はありません。


自分で文字列を解析する必要があるようです:

uses
  varutils;

function MyVarDateFromStr(const strIn: WideString; LCID: DWORD; dwFlags: Longint;
  out dateOut: TDateTime): HRESULT; stdcall;
begin
  // write your parser here and return a valid 'dateOut'
end;


procedure TForm1.Button1Click(Sender: TObject);
var
  LDateTimeVar: Variant;
  LDateTime: TDateTime;
begin
  varutils.VarDateFromStr := MyVarDateFromStr;   // replace the broken function

  // Current date separator in OS settings is ';'
  LDateTimeVar := '07;12;18';
  LDateTime := VarToDateTime(LDateTimeVar);
  // Expected LDateTime = '07;12;18',
  // but will be LDateTime = '07;18;12'
  ShowMessage(DateToStr(LDateTime));
end;
于 2012-07-18T17:55:08.003 に答える