Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   StrToDate EX (https://www.delphipraxis.net/152401-strtodate-ex.html)

Gruber_Hans_12345 21. Jun 2010 15:42

StrToDate EX
 
suche eine StrToDate funktion, die etwas mehr kann.
ich möchte hier auch einen Formatstring übergeben können

wie zb
Delphi-Quellcode:
StrToDateEx('YYYYMMDD', '20100621');
StrToDateEx('DD.MM.YYYY', '21.06.2010');
StrToDateEx('DD/MM/YYYY', '21/06/2010');
ideal wäre, wenn es auch noch Uhrzeit kann

Kennt wer solch ne funktion?

rollstuhlfahrer 21. Jun 2010 15:43

AW: StrToDate EX
 
FormatDateTime gibt es schon bei Delphi und die kann genau das, was du suchst. (War nicht gesucht)
vllt. hilft das hier: http://forum.delphi-treff.de/showthr...ormat-YYYYMMDD , ansonsten selbst parsen und mit EncodeDate arbeiten

Bernhard

bernau 21. Jun 2010 15:46

AW: StrToDate EX
 
Zitat:

Zitat von rollstuhlfahrer (Beitrag 1030682)
FormatDateTime gibt es schon bei Delphi und die kann genau das, was du suchst.

Das hat er aber nicht gesucht. Er möchte einen String übergeben. DAzu die Formatierung und als ergebnis möchte er ein TDatetime haben.

mkinzler 21. Jun 2010 15:56

AW: StrToDate EX
 
Das kann die überladenen Version von StrToDate()

Gruber_Hans_12345 21. Jun 2010 16:21

AW: StrToDate EX
 
Zitat:

Zitat von mkinzler (Beitrag 1030688)
Das kann die überladenen Version von StrToDate()

Wie kann ich das dann verwenden?

Vorallem in dem Fall ohne Separator?

Gruber_Hans_12345 22. Jun 2010 21:29

AW: StrToDate EX
 
Hat noch wer eine IDee?

Ich möchte ungern das ganze selber parsen, glaube nicht, das sowas nicht schon wo existiert ....

Sir Rufo 23. Jun 2010 02:07

AW: StrToDate EX
 
Ist ja auch so schwer, das zu parsen :mrgreen:

Da hast du aber Glück, dass ich diese Funktion für mein aktuelle Projekt benötige.

Delphi-Quellcode:
StrToDateFmt( '20100621', 'YYYYMMDD')
=> 21.06.2010
Delphi-Quellcode:
StrToDateFmt( '21.06.2010', 'DD.MM.YYYY')
=> 21.06.2010
Delphi-Quellcode:
StrToDateFmt( '21/06/2010', 'DD/MM/YYYY')
=> 21.06.2010

Als besonderes Schmankerl kannst du auch eine Format-Liste mitgeben.
Delphi-Quellcode:
StrToDateFmt( '20100621', [ 'DD.MM.YYYY', 'DD/MM/YYYY', 'YYYYMMDD' ] )
=> 21.06.2010
Delphi-Quellcode:
StrToDateFmt( '21.06.2010', [ 'DD.MM.YYYY', 'DD/MM/YYYY', 'YYYYMMDD' ] )
=> 21.06.2010
Delphi-Quellcode:
StrToDateFmt( '21/06/2010', [ 'DD.MM.YYYY', 'DD/MM/YYYY', 'YYYYMMDD' ] )
=> 21.06.2010

Ich benötige diese Unit für eine Eingabe-Maske, wo ein Datum möglichst flexibel und schnell erfasst werden soll.
Und da Buchhalter ja manchmal auch tippfaul (oder auch von anderer SW verwöhnt sind) braucht es halt so eine Funktion.

Delphi-Quellcode:
unit uStrToDateFmt;

interface

function TryStrToDateFmt( const AStr, AFmt : string; var AResult : TDateTime ) : Boolean; overload;
function TryStrToDateFmt( const AStr : string; const AFmt : array of string; var AResult : TDateTime ) : Boolean;
  overload;
function StrToDateFmt( const AStr, AFmt : string ) : TDateTime; overload;
function StrToDateFmt( const AStr : string; const AFmt : array of string ) : TDateTime; overload;
function StrToDateFmtDef( const AStr, AFmt : string; const default : TDateTime ) : TDateTime; overload;
function StrToDateFmtDef( const AStr : string; const AFmt : array of string; const default : TDateTime ) : TDateTime;
  overload;

implementation

uses
  SysUtils, SysConst, StrUtils;

// --- aus SysUtils kopiert --- START ---

procedure ConvertError( ResString : PResStringRec ); local;
  begin
    raise EConvertError.CreateRes( ResString );
  end;

procedure ConvertErrorFmt( ResString : PResStringRec; const Args : array of const ); local;
  begin
    raise EConvertError.CreateResFmt( ResString, Args );
  end;

// --- aus SysUtils kopiert --- ENDE ---

function StrToDateFmtDef( const AStr, AFmt : string; const default : TDateTime ) : TDateTime;
  begin
    if not TryStrToDateFmt( AStr, AFmt, Result ) then
      Result := default;
  end;

function StrToDateFmtDef( const AStr : string; const AFmt : array of string; const default : TDateTime ) : TDateTime;
  begin
    if not TryStrToDateFmt( AStr, AFmt, Result ) then
      Result := default;
  end;

function StrToDateFmt( const AStr, AFmt : string ) : TDateTime;
  begin
    if not TryStrToDateFmt( AStr, AFmt, Result ) then
      ConvertErrorFmt( @SInvalidDate, [ AStr ] );
  end;

function StrToDateFmt( const AStr : string; const AFmt : array of string ) : TDateTime;
  begin
    if not TryStrToDateFmt( AStr, AFmt, Result ) then
      ConvertErrorFmt( @SInvalidDate, [ AStr ] );
  end;

function TryStrToDateFmt( const AStr : string; const AFmt : array of string; var AResult : TDateTime ) : Boolean;
  var
    idx : Integer;
  begin
    Result := False;
    idx := low( AFmt );
    while not Result and ( idx <= high( AFmt ) ) do
      begin
        Result := Result or TryStrToDateFmt( AStr, AFmt[ idx ], AResult );
        Inc( idx );
      end;
  end;

function TryStrToDateFmt( const AStr, AFmt : string; var AResult : TDateTime ) : Boolean;
  var
    dps, fps : string;
    dpi, fpi : Integer;
    d, m, y : Word;
    idx, yl : Integer;
  begin
    Result := Length( AFmt ) = Length( AStr );
    d := 0;
    m := 0;
    y := 0;
    yl := 0;
    idx := 1;
    while Result and ( idx <= Length( AFmt ) ) do
      begin
        dps := Copy( AStr, idx, 1 );
        dpi := StrToIntDef( dps, -1 );
        fpi := IndexText( Copy( AFmt, idx, 1 ), [ 'D', 'M', 'Y' ] );

        // Wenn wir einen Platzhalter erwischt haben, dann müssen wir dazu auch eine Ziffer haben
        Result := not( ( fpi >= 0 ) and ( dpi < 0 ) );

        case fpi of
          0 : // Tag
            d := d * 10 + dpi;
          1 : // Monat
            m := m * 10 + dpi;
          2 : // Jahr
            begin
              y := y * 10 + dpi;
              Inc( yl );
            end;
        else // Format-Zeichen prüfen
          Result := ( dps = Copy( AFmt, idx, 1 ) );
        end;
        Inc( idx );
      end;

    if Result then
      begin
        // kurze Jahreszahl mit dem aktuellen Jahr erweitern
        case yl of
          0 : // kein Jahr übergeben
            y := CurrentYear;
          1 : // Jahr einstellig übergeben
            if Abs( y - CurrentYear mod 10 ) > 2 then
              y := ( CurrentYear div 10 - 1 ) * 10 + y
            else
              y := CurrentYear div 10 * 10 + y;
          2 : // Jahr zweistellig übergeben
            if Abs( y - CurrentYear mod 100 ) > 10 then
              y := ( CurrentYear div 100 - 1 ) * 100 + y
            else
              y := CurrentYear div 100 * 100 + y;
          3 : // Jahr dreistellig übergeben
            if Abs( y - CurrentYear mod 1000 ) > 10 then
              y := ( CurrentYear div 1000 - 1 ) * 1000 + y
            else
              y := CurrentYear div 1000 * 1000 + y;
        end;
      end;

    if Result then
      Result := TryEncodeDate( y, m, d, AResult );
  end;

end.

Gruber_Hans_12345 23. Jun 2010 10:58

AW: StrToDate EX
 
Danke!!

Sieht sehr gut aus.

Als Anregen für eine zukünftige verion wäre noch perfekt, wenn die funktion auch sowas kann:
Delphi-Quellcode:
StrToDateFmt( '21.06.2010', 'DD.MM.YYYY')
=> 21.06.2010
Delphi-Quellcode:
StrToDateFmt( '21.6.2010', 'DD.MM.YYYY')
=> 21.06.2010
Delphi-Quellcode:
StrToDateFmt( '1.6.2010', 'DD.MM.YYYY')
=> 1.6.2010

aber ansonten perfekt!

Danke nochmal!

Sir Rufo 23. Jun 2010 12:26

AW: StrToDate EX
 
Zitat:

Zitat von Gruber_Hans_12345 (Beitrag 1031009)
Danke!!

Sieht sehr gut aus.

Als Anregen für eine zukünftige verion wäre noch perfekt, wenn die funktion auch sowas kann:
Delphi-Quellcode:
StrToDateFmt( '21.06.2010', 'DD.MM.YYYY')
=> 21.06.2010
Delphi-Quellcode:
StrToDateFmt( '21.6.2010', 'DD.MM.YYYY')
=> 21.06.2010
Delphi-Quellcode:
StrToDateFmt( '1.6.2010', 'DD.MM.YYYY')
=> 1.6.2010

aber ansonten perfekt!

Danke nochmal!

Aber die Funktion kann das doch? Du musst nur alle möglichen Kombinationen als Array mitgeben, dann passt das :mrgreen:
Das war doch gerade das flexible an diesem Konvertierungs-Mopped ;)
Delphi-Quellcode:
StrToDateFmt( 
  DatumStr,
  [ 'DD.MM.YYYY', 'D.MM.YYYY', 'DD.M.YYYY', 'D.M.YYYY',
    'DD.MM.YY', 'D.MM.YY', 'DD.M.YY', 'D.M.YY',
    'DDMMYY', 'DDMMYYYY',
    'YY-MM-DD', 'YYYY-MM-DD' ] )
Das Datum 01.06.2010 wird jetzt aus folgenden Eingaben korrekt erkannt:
Code:
01.06.2010, 1.06.2010, 01.6.2010, 1.6.2010, 01.06.10, 1.06.10, 01.6.10, 1.6.10, 010610, 01062010, 10-06-01, 2010-06-01


Alle Zeitangaben in WEZ +1. Es ist jetzt 23:55 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