- Also die Werte bekommt man von Microsoft (die haben ja auch Windows gebaut, also wissen die das auch am besten )
- Wenn du dir mal TFormatSettings im Quelltext (oder auch Online-Hilfe) anschaust, stellst du fest, da gibt es auch einen Constructor. Mal schauen, was der so zu bieten hat ... oha, da gibt es ja sogar 3 Varianten TFormatSettings.Create und eine besagt, dass auch dieses möglich ist TFormatSettings.Create( 'en-US' );
Aha, geht ja schon mal ganz einfach.
Jetzt mal zu
VarToDateTime und
StrToDateTime
Die Online-Hilfe lässt einen hier ein wenig im Regen stehen, so dass man hier auf den Quelltext angewiesen ist.
StrToDateTime
ist eine Pascal-Funktion, die z.B. erhebliche Schwierigkeiten hat, wenn man als Trennzeichen ein Leerzeichen nimmt.
Diese Funktion wird innerhalb von StrToDateTime aufgerufen und entfernt alle Leerzeichen, bis das Trennzeichen gefunden wird
Delphi-Quellcode:
function ScanChar(const S: string; var Pos: Integer; Ch: Char): Boolean;
begin
Result := False;
ScanBlanks(S, Pos);
if (Pos <= Length(S)) and (S[Pos] = Ch) then
begin
Inc(Pos);
Result := True;
end;
end;
VarToDateTime
ist da etwas anders aufgebaut und ruft - nach einigem Hin- und Hergewurschtel - folgendes auf
Delphi-Quellcode:
VarDateFromStr: function(const strIn: WideString; LCID: DWORD; dwFlags: Longint;
out dateOut: TDateTime): HRESULT; stdcall;
Es sieht komisch aus, liegt aber daran, dass hier eine Variable definiert wird, die eine
DLL-Funktion aufruft. Die
DLL wird per LateBinding eingebunden.
Schlussendlich wird also eine Windows-Funktion für die Konvertierung bemüht.
Interessant ist der Parameter
LCID: DWORD
. Diese Funktion kann also auch je nach LCID entsprechend reagieren ... warum macht die das also nicht?
Der Grund liegt hier, da irgendwann innerhalb von VarToDateTime einmal diese Funktion aufgerufen wird:
Delphi-Quellcode:
function VarToDateAsString(
const V: TVarData): TDateTime;
var
S: WideString;
D: Double;
LResult: HResult;
begin
_VarToWStr(S, V);
LResult := VarDateFromStr(S, VAR_LOCALE_USER_DEFAULT, 0, Result);
case LResult
of
VAR_OK:;
// in this case the OS function has put the value into result
VAR_TYPEMISMATCH:
if not TryStrToDate(S, Result)
then
if TryStrToFloat(S, D)
then
Result := D
else
VarResultCheck(VAR_TYPEMISMATCH, V.VType, varDate);
else
VarResultCheck(LResult, V.VType, varDate);
end;
end;
Es gibt auch - soweit ich das überschauen kann - keine überladene Funktion, wo man die gewünschte LCID übergeben kann.
Die Lösung besteht darin, z.B. direkt die Funktion aufzurufen:
Delphi-Quellcode:
function APIStrToDateTime(
const S : WideString; LCID : Cardinal ) : TDateTime;
var
LResult : HResult;
begin
if VarDateFromStr( S, LCID, 0, Result ) <> VAR_OK
then
raise EConvertError.CreateFmt( '
"%s" ist kein gültiges Datum', [S] );
end;
procedure TForm1.Button1Click( Sender : TObject );
begin
ShowMessage( DateToStr( APIStrToDateTime( '
15 Dec 2012', 1033 ) ) );
end;