2017-09-01 3 views
0

J'utilise Delphi7.Delphi-7: convertir une chaîne formatée aaaaammjj (format sans séparateur) en objet DateTime

J'ai le format de date défini sur aaaaammjj (peut prendre n'importe quel format de date sans séparateur). Quand j'essaie StrToDate('20170901'), c'est une erreur de lancer.

Je veux soutenir tous les formats de date valides (peut être utilisé par différents clients dans différentes zones.)

J'ai essayé avec VarToDateTime mais il est aussi ne fonctionne pas.

Si le même problème existe pour DateToStr(), veuillez également me guider.

+0

@LURD: Mon erreur, j'ai mis à jour les détails. Si possible s'il vous plaît retirer le marquage négatif afin qu'au moins je puisse obtenir ma solution. Merci d'avance. –

+0

Il est assez trivial de choisir les composants d'une telle chaîne en utilisant, par exemple, Copier. Ils peuvent ensuite être transmis à StrToInt, puis à EncodeDate. –

+0

@DavidHeffernan: mais que se passe-t-il si le réglage régional du système a été changé en '1-sept-2017'. Je dois prendre soin de tous les formats possibles. –

Répondre

4

Pour convertir cette chaîne en TDateTime, divisez la chaîne en ses composants year, month et day et transmettez-les à la fonction EncodeDate().

var 
    myStr: string; 
    myDate: TDate; 
begin 
    myStr := '20170901'; 
    myDate := EncodeDate(
    StrToInt(Copy(MyStr, 1, 4)), 
    StrToInt(Copy(MyStr, 5, 2)), 
    StrToInt(Copy(MyStr, 7, 2)) 
); 
    ... 
end; 
+0

Malheureusement, vous avez négligé de comptabiliser une indexation de chaînes basée sur 1. Et ne pas utiliser une variable pour la chaîne est faible. Enfin, le demandeur veut faire beaucoup plus que cela, mais la question n'est pas claire. –

+0

C'était une suggestion d'un moyen de résoudre son problème, bien sûr, il peut appliquer les meilleures pratiques. Je suis pratique. – WellingtonD

+0

Vous avez ignoré le détail dans mon commentaire –

5

Vous obtenez une erreur car votre chaîne d'entrée ne correspond pas aux paramètres régionaux de votre machine pour les chaînes de date/heure.

Normalement, je suggère d'utiliser la fonction StrToDate() dans l'unité SysUtils, l'établissement de ses variables globales ShortDateFormat et DateSeparator au préalable, puis les restaurer par la suite (Delphi 7 est antérieure à l'introduction du dossier TFormatSettings), par exemple:

uses 
    ..., SysUtils; 

var 
    OldShortDateFormat: string; 
    OldDateSeparator: Char; 
    input: string; 
    dt: TDateTime; 
begin 
    input := ...; 

    OldShortDateFormat := ShortDateFormat; 
    OldDateSeparator := DateSeparator; 
    ShortDateFormat := 'yyyymmdd'; // or whatever format you need... 
    DateSeparator := '/'; // or whatever you need 
    try 
    dt := StrToDate(input); 
    finally 
    ShortDateFormat := OldShortDateFormat; 
    DateSeparator := OldDateSeparator; 
    end; 

    // use dt as needed... 
end; 

Malheureusement, StrToDate()nécessite la chaîne d'entrée pour avoir un séparateur entre les composants (ie 2017/09/01), mais votre chaîne d'entrée ne fonctionne pas (20170901). StrToDate() n'autorise pas DateSeparator à être défini sur #0 lors de l'analyse d'une chaîne, même si le ShortDateFormat ne spécifie aucun séparateur dans le format.

Ce qui laisse qu'une seule option - analyser la chaîne manuellement pour extraire les composants individuels, puis utilisez la fonction EncodeDate() dans l'unité SysUtils, par exemple:

uses 
    ..., SysUtils; 

var 
    wYear, wMonth, wDay: Word; 
    input: string; 
    dt: TDateTime; 
begin 
    input := ...; 

    wYear := StrToInt(Copy(input, 1, 4)); 
    wMonth := StrToInt(Copy(input, 5, 2)); 
    wDay := StrToInt(Copy(input, 7, 2)); 
    // or in whatever order you need... 

    dt := EncodeDate(wYear, wMonth, wDay); 

    // use dt as needed... 
end; 

La fonction DateToStr() est également soumise aux paramètres régionaux . Cependant, cela permet d'omettre le DateSeparator dans la sortie. Ainsi, vous pouvez:

  1. utilisation DateToStr(), définissant la variable ShortDateFormat globale au format souhaité:

    uses 
        ..., SysUtils; 
    
    var 
        OldShortDateFormat: string; 
        dt: TDateTime; 
        output: string; 
    begin 
        dt := ...; 
    
        OldShortDateFormat := ShortDateFormat; 
        ShortDateFormat := 'yyyymmdd'; // or whatever format you need... 
        try 
        output := DateToStr(dt); 
        finally 
        ShortDateFormat := OldShortDateFormat; 
        end; 
    
        // use output as needed... 
    end; 
    
  2. extraire les composants de date individuels du TDateTime en utilisant la fonction DecodeDate() dans l'unité SysUtils , puis formatez votre propre chaîne avec les valeurs année/mois/jour comme vous le souhaitez:

    uses 
        ..., SysUtils; 
    
    var 
        wYear, wMonth, wDay: Word; 
        dt: TDateTime; 
        output: string; 
    begin 
        dt := ...; 
    
        DecodeDate(dt, wYear, wMonth, wDay); 
        output := Format('%.4d%.2d%.2d', [wYear, wMonth, wDay]); 
    
        // use output as needed... 
    end; 
    
+0

Très belle approche la seconde – WellingtonD