AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

VarToDateTime mit englischem Datum

Ein Thema von FunThomas · begonnen am 14. Jan 2012 · letzter Beitrag vom 15. Jan 2012
Antwort Antwort
Seite 1 von 2  1 2      
FunThomas

Registriert seit: 15. Jul 2008
10 Beiträge
 
#1

VarToDateTime mit englischem Datum

  Alt 14. Jan 2012, 20:20
Hallo,

ich habe nen kleines Problem beim Einlesen eines Datums. Ich versuche ein Datum z.B '29 Dec 2011' auf einem deutschem System in einen TDateTime zu wandeln.
das klappt soweit ganz gut für Datumsangaben mit Monat Jan (ist im engl identisch) allerdings wenn ich folgendes Beispiel nehme schläg es schon fehl

Code:
var
  myDate : TDateTime;

  Datum  : string;
  neues_datumsformat : TFormatSettings;

begin
  GetLocaleFormatSettings(LOCALE_SYSTEM_DEFAULT, orginales_datumsformat);
  orginales_datumsformat.ShortDateFormat := 'dd mmm yyyy';
  orginales_datumsformat.LongDateFormat := 'dd mmm yyyy';
  orginales_datumsformat.DateSeparator := ' ';
  myDate := VarToDateTime('29 Dec 2011');
end;
Gibt es da irgendeine Möglichkeit dieses Datumsformat vernünftig einzulesen ?

Gruß,
Thomas
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#2

AW: VarToDateTime mit englischem Datum

  Alt 14. Jan 2012, 21:11
Du beschreibst doch schon die Ursache.

Du konvertierst immer noch mit den deutschen Monats-Abkürzungen (weil deutsches System).
Hol dir doch die englischen/amerikanischen FormatSettings und nicht die vom System.
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
Benutzerbild von implementation
implementation

Registriert seit: 5. Mai 2008
940 Beiträge
 
FreePascal / Lazarus
 
#3

AW: VarToDateTime mit englischem Datum

  Alt 14. Jan 2012, 21:35
Zur Not mach's so:
Delphi-Quellcode:
function ConvertDate(const str: string): TDate;
var i: byte; d, m, y: word; mn: string;
const months: array[1..12] of string = ('jan','feb','mar','apr','may',
               'jun','jul','aug','sep','oct','nov','dec');
  procedure Next;
  begin
    Inc(i);
  end;
  function GetNum: word;
  begin
    Result := 0;
    while str[i] in ['0'..'9'] do begin
      Result := Result*10 + Ord(str[i]) - Ord('0');
      Next;
    end;
  end;
  procedure SkipWhite;
  begin
    while str[i] in [#9,#32] do Next;
  end;
  function GetName: string;
  begin
    Result := '';
    while str[i] in ['a'..'z','A'..'Z'] do begin
      if str[i] in ['a'..'z'] then
        Result := Result + str[i]
      else Result := Result + Chr(Ord(str[i])-Ord('A')+Ord('a'));
      Next;
   end;
  end;
begin
  i := 1;
  d := GetNum;
  SkipWhite;
  mn := GetName;
  SkipWhite;
  y := GetNum;
  for i := 1 to 12 do
    if months[i]=mn then
      m := i;
  if not TryEncodeDate(y,m,d,result) then
    raise EConvertError.Create('Invalid date');
end;

Geändert von implementation (14. Jan 2012 um 21:56 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.132 Beiträge
 
Delphi 12 Athens
 
#4

AW: VarToDateTime mit englischem Datum

  Alt 14. Jan 2012, 22:48
Wieso den Umweg über Delphi-Referenz durchsuchenVarToDateTime, oder hast du etwas gegen Delphi-Referenz durchsuchenStrToDateTime?

Du ließt die Systemwerte in orginales_datumsformat ein und veränderst diese Variable.
Gefunden hab ich aber nur die Deklaration für neues_datumsformat.

Außerdem setzt du nirgendwo die geänderten Werte, bzw. weißt sie nirgends zu, so daß sie verwendet werden könnten.

PS: StrToDateTime kann man die FormatSettings auch direkt mitgeben, ohne sie (programm)global ändern zu müssen.


@implementation: Man kann (zumindestens in Delphi funktioniert es ganz gut) auch vorhandene Funktionen nutzen und muß nicht unbedingt alles selber machen.
Man muß nur eben die richtigen Funktionen nutzen, bzw. den verwendeten Funktionen auch dir richtigen Einstellungen geben.

Also noch auf Sir Rufo hören oder zumindestens die FormatSettings selber befüllen.
(LOCALE_SYSTEM_DEFAULT = aktuelle Systemeinstellung, aber alternativ kann man nur was auslesen, welches auch installiert ist, also nicht unbedingt blind drauf verlassen, daß es andere Sprachen überhaupt gibt.)
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests

Geändert von himitsu (14. Jan 2012 um 22:57 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von implementation
implementation

Registriert seit: 5. Mai 2008
940 Beiträge
 
FreePascal / Lazarus
 
#5

AW: VarToDateTime mit englischem Datum

  Alt 14. Jan 2012, 23:26
@implementation: Man kann (zumindestens in Delphi funktioniert es ganz gut) auch vorhandene Funktionen nutzen und muß nicht unbedingt alles selber machen.
Kann man?

while not HinterDieOhrenGeschrieben do Writeln('Ich werde von nun an alles über die RTL machen.');

Ich benutz' normal nichtmal TList, hab 'ne eigene Alternative. So, und jetzt steinigt mich!

Geändert von implementation (14. Jan 2012 um 23:30 Uhr)
  Mit Zitat antworten Zitat
FunThomas

Registriert seit: 15. Jul 2008
10 Beiträge
 
#6

AW: VarToDateTime mit englischem Datum

  Alt 15. Jan 2012, 10:32
Hi Leute,
sorry dass ich nicht so ein Delphi-Crack bin wie Ihr
Ich probiere hier leider rum und kriege das leider nicht hin, der meckert jedesmal dass es kein gültiges Datum ist
Wenn ich z.B.
Code:
        GetLocaleFormatSettings(2057, orginales_datumsformat);
        orginales_datumsformat.ShortDateFormat := 'dd mmm yyyy';
        orginales_datumsformat.LongDateFormat := 'dd mmm yyyy';
        orginales_datumsformat.DateSeparator := ' ';
        myDate := StrToDateTime('29 Dec 2011',orginales_datumsformat);
funktioniert das ganze nicht obwohl die orginales_datumsformat.ShortMonthNames[12] = 'Dec' ist.
Falls einer nen Tip hat wieso dann würde ich mich darüber freuen.

kann mir eigentlich jemand sagen wo ich die Konstantennamen für LOCALE_SYSTEM_DEFAULT und die einzelnen Länder finde ? Die Hilfen zeigen mir nur den Typ aber die Konstanten sind leider nirgends aufgeführt. Ich habe jetzt nur bei Microsoft die LCID 2057 für en-UK gefunden, ist aber blöd eine Zahlenkonstante in seinem Progrämmchen zu verwenden.

Wenn ich jetzt über den Umweg
Code:
myDate := VarToDateTime('29 Dec 2011');
gehe passen meine lokalen Settings nicht -> mit welcher Funktion kann ich die auf z.B. en-UK ändern ?

Gruß,
Thomas
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#7

AW: VarToDateTime mit englischem Datum

  Alt 15. Jan 2012, 11:57
  1. Also die Werte bekommt man von Microsoft (die haben ja auch Windows gebaut, also wissen die das auch am besten )
  2. Wenn du dir mal Delphi-Referenz durchsuchenTFormatSettings 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 Delphi-Referenz durchsuchenTFormatSettings.Create und eine besagt, dass auch dieses möglich ist TFormatSettings.Create( 'en-US' );
Aha, geht ja schon mal ganz einfach.

Jetzt mal zu Delphi-Referenz durchsuchenVarToDateTime und Delphi-Referenz durchsuchenStrToDateTime
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;
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
FunThomas

Registriert seit: 15. Jul 2008
10 Beiträge
 
#8

AW: VarToDateTime mit englischem Datum

  Alt 15. Jan 2012, 12:11
Besten Dank für die umfangreiche Antwort aber darauf wäre ich bestimmt nicht alleine gekommen

Da hätte ich mir eher ne suchen & ersetzen Routine gebaut die das in Zahlen konvertiert und dann das über Standard erledigt *g*

Besten Dank !
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.132 Beiträge
 
Delphi 12 Athens
 
#9

AW: VarToDateTime mit englischem Datum

  Alt 15. Jan 2012, 14:01
StrToDateTime wäre eh nicht gegangen.
Das versucht ja Datum und Zeit zu lesen, aber wenn es keine Zeit gibt, dann wäre StrToDate besser.

Aber ich seh auch grade, daß dieses wirklich mit ' ' Probleme hat und es ist auch sooo doof, daß es mit Wörtern nicht klar kommt, da alle Werte nur als Zahlen ausgelesen werden.

Mir fällt auch auf, daß ich bis jetzt immer zufällig ein Trennzeichen drin hatte und auch nur Zahlen. pps:

Schon komisch, daß das so noch nicht aufgefallen und schon lange behoben ist, wo doch im englischen (amerikanischen) Datumssystem standardmäßig "dd mmmm yyyy" vorkommt, also Wort+Leerzeichen.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests

Geändert von himitsu (15. Jan 2012 um 14:07 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von implementation
implementation

Registriert seit: 5. Mai 2008
940 Beiträge
 
FreePascal / Lazarus
 
#10

AW: VarToDateTime mit englischem Datum

  Alt 15. Jan 2012, 16:45
Schon komisch, daß das so noch nicht aufgefallen und schon lange behoben ist, wo doch im englischen (amerikanischen) Datumssystem standardmäßig "dd mmmm yyyy" vorkommt, also Wort+Leerzeichen.
Manchmal ist selberschreiben eben doch die bessere Option
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 09:16 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz