IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage Delphi Discussion :

DateTimeToStr et StrToDateTime non réciproques


Sujet :

Langage Delphi

  1. #1
    Inactif
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    97
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 97
    Par défaut DateTimeToStr et StrToDateTime non réciproques
    Bonjour à tous,

    J'ai un petit problème pour utiliser DateTimeToStr et StrToDateTime avec leur format étendu (c'est à dire avec un 'FormatSettings' spécifié).

    Voici mon code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    unit Princ;
     
    interface
     
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls;
     
    type
      TForm1 = class(TForm)
        Label1: TLabel;
        Button1: TButton;
        Label2: TLabel;
        Label3: TLabel;
        procedure Button1Click(Sender: TObject);
      private
        { Déclarations privées }
      public
        { Déclarations publiques }
      end;
     
    var
      Form1: TForm1;
     
    implementation
     
    {$R *.dfm}
     
    procedure TForm1.Button1Click(Sender: TObject);
     
    Var
      MyFormatSettings: TFormatSettings;
      Date1S: String;
      Date2S: String;
      Date1: TDateTime;
      Date2: TDateTime;
      Date3: TDateTime;
      Date4: TDateTime;
     
    begin
      {Initialisation des dates exemple}
      Date1S:='22/04/2008 18:00:00';
      Date2S:='23/04/2008 21:00:00';
      Date1:=StrToDateTime(Date1S);
      Date2:=StrToDateTime(Date2S);
      {On va chercher le format setting courant}
      GetLocaleFormatSettings(LOCALE_SYSTEM_DEFAULT,MyFormatSettings);
      {On change le format setting}
      MyFormatSettings.ShortDateFormat:='yyyyMMdd';
      MyFormatSettings.LongTimeFormat:='hhmmss';
      {On affiche : le format setting est pris en compte DateTime -> String}
      Label1.Caption:=DateTimeToStr(Date1,MyFormatSettings);
      Label2.Caption:=DateTimeToStr(Date2,MyFormatSettings);
      {vvv Et là ça plante String -> DateTime ne marche pas avec le même FormatSetting ! Bizarre non ??? vvv}
      Date3:=StrToDateTime(Label1.Caption,MyFormatSettings);
      Date4:=StrToDateTime(Label2.Caption,MyFormatSettings);
    end;
     
    end.
    On peut voir que la fonction DateTimeToStr avec un FormatSettings spécifié marche très bien, mais que dès que l'on utilise StrToDateTime avec le même FormatSettings et la Date initialisée avec les précédentes procédures, ça plante

    Bizarre non ? Ces fonctions ne seraient-elles pas réciproques ou ai-je raté un épisode ?

    Je tiens à préciser qu'autant faire se peut, j'aimerais garder une variable FormatSettings particulière car j'utilise des conversions de date ailleurs dans mon programme principal : vous aurez compris que ceci n'est qu'un programme 'exemple'

    Je vous remercie des réponses que vous voudrez bien m'apporter.

    A+

    Philippe.

  2. #2
    Expert confirmé
    Avatar de Cl@udius
    Homme Profil pro
    Développeur Web
    Inscrit en
    Février 2006
    Messages
    4 878
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Février 2006
    Messages : 4 878
    Par défaut
    Salut

    Si l'utilisation de DateTimeToStr reste assez souple, la fonction inverse StrToDateTime l'est moins.

    Tu obtiens l'erreur EConvertError car la chaine doit absolument contenir les séparateurs (DateSeparator et TimeSeparator) pour pouvoir être convertie.
    Donc il te suffit de réinjecter ces séparateurs dans la chaine avec une petite fonction comme celle-ci:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    function InsertDateTimeSep(ADate: string; const DateSep: Char = '/';
      const TimeSep: Char = ':'): string;
    begin
      Result := Copy(ADate, 1, 4) + DateSep + Copy(ADate, 5, 2) + DateSep +
        Copy(ADate, 7, 5) + TimeSep + Copy(ADate, 12, 2) + TimeSep +
        Copy(ADate, 14, 2);
    end;
    @+ Claudius

  3. #3
    Inactif
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    97
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 97
    Par défaut Non...
    Je te remercie grandement de ton aide Claudius, mais cette solution ne me convient pas du tout...

    En effet, le but du jeu est d'utiliser la fonction StrToDateTime avec un argument de format déterminé afin que, in fine, l'utilisateur puisse transmettre la chaine de caractère correspondant au formatage pour avoir à la fois un affichage de la date correspondant au formatage (...ce qui marche actuellement...), mais aussi que ce formatage soit pris en compte dans la transformation en format DateTime dans le but de pouvoir comparer deux dates quelque soit le format transmis.

    En effet, une fois la transformation en DateTime effectuée, il existe une fonction de comparaison de deux dates qui permet de dire laquelle est plus grande que l'autre... Et de pouvoir afficher le résultat de cette comparaison à l'écran.

    Donc, comme on veut pouvoir transmettre le format par l'utilisateur, cela suppose que la résolution du problème ne puisse pas être résolue par l'écriture d'une fonction ad-hoc.

    Merci de ton aide.

    A+

    Philippe.

  4. #4
    Expert confirmé
    Avatar de Cl@udius
    Homme Profil pro
    Développeur Web
    Inscrit en
    Février 2006
    Messages
    4 878
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Février 2006
    Messages : 4 878
    Par défaut
    OK, je comprends mieux la situation.

    Donc ton problème est de pouvoir traduire une chaine de caractère donnée connaissant son format. Sachant que ce format peut ne pas contenir de séparateurs de date et/ou d'heure.
    Et bien c'est là que le bât blesse car, je me répète, la fonction StrToDateTime exige ces séparateurs.

    Il va falloir trouver autre chose.

    Est-ce la liste des formats que te fournit l'utilisateur est figée ?
    Ou au contraire, dois-tu gérer tous les formats possibles y compris les plus exotiques ?

    Car la difficulté majeure est de pouvoir interpréter cette date/heure sans les séparateurs. Ce qui n'est pas gagné d'avance: où s'arrête le mois, et où commence le jour, ...

    @+ Claudius

  5. #5
    Inactif
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    97
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 97
    Par défaut Solution...
    Bonjour Claudius,

    En fait, pour répondre à ta question, l'idéal serait que l'utilisateur puisse reprendre les formats standards définis dans TFormatSettings c'est à dire yyyy pour l'année sur 4 digits, MM pour le mois sur 2 digits, etc.

    Comme d'après toi, StrToDateTime ne peut fonctionner sans les fameux séparateurs (ce que je trouve débile, mais bon ), et ben, j'ai réécrit cette fonction

    Et d'après mes premiers tests, ça marche nickel

    Pour le moment, je me suis cantonné à gérer yyyy, MM, dd, hh, mm et ss... Vu que c'était les seuls dont j'avais besoin, je me suis pas pris la tête plus que ça

    La fonction est réécrite (préfixée avec mes initiales : on ne mélange pas les torchons et les serviettes ) et recrée un format de Date en chaîne de caractère classique. A partir de ce format, on utilise la fonction de base StrToDateTime et hop, le tour est joué...

    Le seul problème c'est que ma fonction n'est pas 'thread safe' vu qu'un appel à StrToDateTime est fait... Mais bon, j'ai pas creusé plus que ça vu que mon programme n'utilise pas de threads de toutes façons...

    Si ça se trouve, avec un appel à StrToDateTime version ThreadSafe, ça marche... Faudrait tester...

    Voili voilou !

    Merci de ton aide en tous cas Claudius.

    Bonne continuation.

    Philippe.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    {Fonction Str -> DateTime fonctionnant avec un Format Setting. Remplace StrToDateTime car elle marche pas. On la réécrit donc.}
    {Prise en compte de MyFormatSettings.ShortDateFormat et MyFormatSettings.LongTimeFormat en prenant en compte que TDateTime est la concaténation des deux séparées par un espace}
    {Uniquement prise en compte de yyyy, MM, dd, hh, mm, ss -> le reste viendra plus tard en fonction des besoins}
    Function PNStrToDateTime(const S:string;const FormatSettings:TFormatSettings):TDateTime;
     
    Var
      DateTemp: String;
      FormatTemp: String;
      DateToReturn: TDateTime;
      PosC: Integer;
      LongS: Integer;
      LongF: Integer;
      Traite: Boolean;
      FormatTrait: String;
      Annee: String;
      Mois: String;
      Jour: String;
      Heure: String;
      Minute: String;
      Seconde: String;
      SeparaDate: Char;
      SeparaHeure: Char;
     
    Begin
      FormatTemp:=FormatSettings.ShortDateFormat+' '+FormatSettings.LongTimeFormat;
      SeparaDate:=FormatSettings.DateSeparator;
      SeparaHeure:=FormatSettings.TimeSeparator;
      LongS:=Length(S);
      {Prise en compte yyyy}
      FormatTrait:='yyyy';
      LongF:=Length(FormatTrait);
      PosC:=Pos(FormatTrait,FormatTemp);
      Traite:=(PosC>0) And (PosC+LongF-1<=LongS);
      If Traite Then
        Annee:=Copy(S,PosC,LongF)
      Else
        Annee:='1900';
      {Prise en compte MM}
      FormatTrait:='MM';
      LongF:=Length(FormatTrait);
      PosC:=Pos(FormatTrait,FormatTemp);
      Traite:=(PosC>0) And (PosC+LongF-1<=LongS);
      If Traite Then
        Mois:=Copy(S,PosC,LongF)
      Else
        Mois:='01';
      {Prise en compte dd}
      FormatTrait:='dd';
      LongF:=Length(FormatTrait);
      PosC:=Pos(FormatTrait,FormatTemp);
      Traite:=(PosC>0) And (PosC+LongF-1<=LongS);
      If Traite Then
        Jour:=Copy(S,PosC,LongF)
      Else
        Jour:='01';
      {Prise en compte hh}
      FormatTrait:='hh';
      LongF:=Length(FormatTrait);
      PosC:=Pos(FormatTrait,FormatTemp);
      Traite:=(PosC>0) And (PosC+LongF-1<=LongS);
      If Traite Then
        Heure:=Copy(S,PosC,LongF)
      Else
        Heure:='12';
      {Prise en compte mm}
      FormatTrait:='mm';
      LongF:=Length(FormatTrait);
      PosC:=Pos(FormatTrait,FormatTemp);
      Traite:=(PosC>0) And (PosC+LongF-1<=LongS);
      If Traite Then
        Minute:=Copy(S,PosC,LongF)
      Else
        Minute:='00';
      {Prise en compte ss}
      FormatTrait:='ss';
      LongF:=Length(FormatTrait);
      PosC:=Pos(FormatTrait,FormatTemp);
      Traite:=(PosC>0) And (PosC+LongF-1<=LongS);
      If Traite Then
        Seconde:=Copy(S,PosC,LongF)
      Else
        Seconde:='00';
      DateTemp:=Jour+SeparaDate+Mois+SeparaDate+Annee+' '+Heure+SeparaHeure+Minute+SeparaHeure+Seconde;
      DateToReturn:=StrToDateTime(DateTemp);
      PNStrToDateTime:=DateToReturn;
    End;

Discussions similaires

  1. Byte[] toString().getBytes() non réciproque?
    Par irumi dans le forum Débuter avec Java
    Réponses: 4
    Dernier message: 08/06/2011, 14h32
  2. apprentissage non supervisé .......
    Par ratbert dans le forum Statistiques, Data Mining et Data Science
    Réponses: 7
    Dernier message: 22/02/2008, 12h23
  3. [CR8][Delphi6] erreur imprimante non supportée
    Par Sebastien L. dans le forum SDK
    Réponses: 3
    Dernier message: 12/09/2002, 15h42
  4. Form principale non visible au demarrage!!!!
    Par toufou dans le forum Composants VCL
    Réponses: 2
    Dernier message: 20/07/2002, 21h49
  5. Réponses: 6
    Dernier message: 21/06/2002, 14h48

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo