Partage
  • Partager sur Facebook
  • Partager sur Twitter

Convertir un Long en Date

TDateTime

Sujet résolu
    2 août 2008 à 17:58:03

    Bonjour à tous.

    Je suis en train de clôner un outils Windows sous Linux.

    Cet outils travail sur des fichiers, et créer un Header. Dans ce header est stoqué une date avec le type delphi TDateTime.
    Je désire donc le convertir en date.

    Comment peux-t-on ca ? Merci :)

    Edit: je vient de trouver une définition de TDateTime :
    Le type spécial TDate ou TDateTime représente pour sa partie entière le nombre de jours écoulés depuis le 30/12/1899 et pour sa partie fractionnaire le nombre d'heure depuis minuit (partie fractionnaire nulle pour TDate).
    • Partager sur Facebook
    • Partager sur Twitter
    Anonyme
      2 août 2008 à 19:32:04

      Quand tu dis que tu veux convertir en date, tu parles d'un type date ou d'une sortie du type 1/08/2008 ?
      Dans le cas d'une sortie il te suffit de coder un algorithmes qui va ajouter un jour a 30/12/1899 tant que ja variable TDateTime n'est pas a 0.xxxxx.
      • Partager sur Facebook
      • Partager sur Twitter
        2 août 2008 à 19:44:08

        Bonjour yamashi,

        Merci de ton poste.

        Oui j'ai un entier qui représente le nombre de jours de puis le 30/12/1899, et je désire l'afficher en texte comme 02/08/2008.

        J'ai bien compris ce principe. Enffet je voulais pas re-coder un truc qui aurait déjà été coder, surtout qu'il y a le problème des années bissextile, etc ...
        • Partager sur Facebook
        • Partager sur Twitter
        Anonyme
          2 août 2008 à 19:47:48

          Pour les annees bissextile c'est simple, tu fais en sorte que tout les 4 ans a partir de la premiere occurence (1900?) il y est un jour de plus en fevrier.
          • Partager sur Facebook
          • Partager sur Twitter
            2 août 2008 à 19:51:45

            Bon OK, je vais essayer de voire ca ;)

            Merci à toi pour ton aide ! Je vais essayer de voire ce que j'arrive à faire. ( Mais je pense pas être le premier à avoir ce soucis. )

            Bon j'ai fais un bout de code très rapide ( qui ne gère pas encore les années bissextile ), mais j'ai un problème...
            La valeur que j'ai, qui représente les jours depuis 30/12/1899 est 1088642496 ce qui est beaucoup trop si je m'en sort comme jours.

            La valeur devrais être dans les alentours de 39750 a peu prêt pour les jours.

            Alors le truc que j'ai vue aussi, c'est que le TDateTime du Delphi stock Date & Heure.

            Donc là je ne voie pas comment faire pour extraire la date uniquement ... :(
            • Partager sur Facebook
            • Partager sur Twitter
              11 août 2008 à 10:06:20

              Une petite aide s'y vous plait ? :D

              Edit: je vient de trouver enfin quelque chose !! :)

              Un site polonais donne la solution pour convertir le type TDateTime de Delphi en TimeStamp Unix !
              http://blog.malcom.pl/2007/07/23/conve [...] ix-timestamp/

              Donc en résumé, le gas propose ces deux fonctions pour convertir TDateTime -> Unix TimeStamp et Unix TimeStamp -> TDateTime.

              #include <math.h>
              
              inline int TDateTime2UnixTimeStamp(double datetime) {
                      return (int) round((datetime - 25569.0) * 86400);
              }
              
              inline double UnixTimeStamp2TDateTime(int timestamp) {
                      return (timestamp / 86400) + 25569.0;
              }
              

              ( 86400 représente le nombre de secondes dans 1 jour et 25569.0 date de départ d'Unix)

              Donc maintenant je n'ai plus qu'a voire comment jouer avec le TimeStamp pour convertir en date humainement lisible. ^^
              • Partager sur Facebook
              • Partager sur Twitter
                11 août 2008 à 15:47:19

                Salut en C++ il y a déjà une standardisation des dates.

                Pas le type int mais time_t contenu dans <ctime> est conçu pour ça. time_t est le type provenant de la norme UNIX. l'en-tête <ctime> contient une tonne de fonctions pour manipuler et transformer la date prêt à être lu par un humain et à l'inverse.

                notons localtime, difftime, mktime, time...
                la structure tm est ton meilleur ami lors de l'affichage d'une date.

                j'ai C++ isé ton exemple.
                #include <cmath>
                #include <ctime>
                
                inline time_t ConvertTDateTime( double datetime ) 
                {
                    return static_cast<time_t>( round( (datetime - 25569.0) * 86400.0) );
                }
                
                inline double MakeTDateTime(time_t timestamp) 
                {
                    return static_cast<double>( timestamp / 86400 ) + 25569.0;
                }
                


                Ce que je te propose, parce que je n'ai pas d'exemple de TDateTime sous la main c'est de faire le test par toi même. Vérifie que les valeurs converties correspondent.


                time_t est un entier de 64 bits sur la plupart des systèmes maintenant pour éviter le UNIX MILLENIUM BUG. Le bug de l'an 2000 + 38 (Y2K+38). Effectivement en comptant les secondes le nombre de 32 bits signé devrait débordé lors du 19 janvier 2038 à 03:14:07. Mais en représentant la date sur un entier signé de 64 bits nous pouvons représenter des dates précédent la date approximative de la création de l'univers. Ce qui est, semble-t-il, assez long pour être utilisé quelques années.

                http://en.wikipedia.org/wiki/Time_t
                http://en.wikipedia.org/wiki/Year_2038_problem
                http://www.gotapi.com/dinkumc voir la section time.h sous C Standard Library. (ctime redirige là)


                P.S. le calcul des années bisextiles est beacoup plus compliqué que +1 jour à tout les 4 ans (+1 jour à tout les multiple de 4 non multiple de 100 sauf les multiple de 400, compliqué?). Dû à l'ajustement du calendrier grégorien il y a des jours qui ont tout simplement disparus entre le 4 au 15 octobre 1582 qu'il faut prendre en compte. le Daylight Saving Time (DST) aussi qui est important. Et autres conventions mondiales qui pourraient m'avoir échappées.
                http://fr.wikipedia.org/wiki/Bisextile
                http://fr.wikipedia.org/wiki/Calendrier_grégorien

                Mieux vaut utiliser les bibliothèque standard qui prennent déjà tout ça en compte.

                • Partager sur Facebook
                • Partager sur Twitter
                  11 août 2008 à 18:44:30

                  Citation : MatteX

                  Ce que je te propose, parce que je n'ai pas d'exemple de TDateTime sous la main c'est de faire le test par toi même. Vérifie que les valeurs converties correspondent.



                  Okay !! Merci Mr !


                  Citation : MatteX

                  time_t est un entier de 64 bits sur la plupart des systèmes maintenant pour éviter le UNIX MILLENIUM BUG. Le bug de l'an 2000 + 38 (Y2K+38). Effectivement en comptant les secondes le nombre de 32 bits signé devrait débordé lors du 19 janvier 2038 à 03:14:07. Mais en représentant la date sur un entier signé de 64 bits nous pouvons représenter des dates précédent la date approximative de la création de l'univers. Ce qui est, semble-t-il, assez long pour être utilisé quelques années.



                  Merci pour ces infos !


                  Citation : MatteX

                  P.S. le calcul des années bisextiles est beacoup plus compliqué que +1 jour à tout les 4 ans (+1 jour à tout les multiple de 4 non multiple de 100 sauf les multiple de 400, compliqué?). Dû à l'ajustement du calendrier grégorien il y a des jours qui ont tout simplement disparus entre le 4 au 15 octobre 1582 qu'il faut prendre en compte. le Daylight Saving Time (DST) aussi qui est important. Et autres conventions mondiales qui pourraient m'avoir échappées.
                  http://fr.wikipedia.org/wiki/Bisextile
                  http://fr.wikipedia.org/wiki/Calendrier_grégorien

                  Mieux vaut utiliser les bibliothèque standard qui prennent déjà tout ça en compte.



                  Heu ouais ... carrément d'accord avec toi !!! ^^



                  Edit: Bon je ne suis actuellement pas sure du nombre que je récupère...
                  Je m'explique:

                  Je lis ce nombre dans un fichier binaire.
                  Donc j'utilise seekg() de ifstream pour me placer au bon endroit, puis, je lis la valeur sur 4 octets de cette manière:
                  myFile.read( (char *) &intDate, sizeof( int ) );
                  cout << intDate << endl;
                  


                  Ce qui me donne :
                  1088642784


                  Et si je caste ce nombre en double, j'obtiens ca :
                  1.08864e+09


                  Et si j'appelle ConvertTDateTime() j'obtiens :
                  94056527376000

                  Ce qui est extrement trop...


                  Je pense avoir un gros soucis coté récupération et utilisation de la valeur :(


                  Edit 2: Pour tester ton code, j'ai fait ca :
                  time_t temps_act;
                  	time( &temps_act );
                  	cout << endl << "Today : '" << ctime( &temps_act ) << endl;
                  	
                  	double dblTest = tools.MakeTDateTime( temps_act );
                  	time_t newTime = tools.ConvertTDateTime( dblTest );
                  	cout << "Result: '" << ctime( &newTime ) << endl;
                  


                  J'obtiens :
                  Today : 'Mon Aug 11 19:36:50 2008
                  
                  MakeTDateTime( 1218476210 ) = 39671
                  ConvertTDateTime( 39671 ) = 1218412800
                  Result: 'Mon Aug 11 02:00:00 2008
                  • Partager sur Facebook
                  • Partager sur Twitter
                    12 août 2008 à 16:28:26

                    Effectivement j'ai la même erreur chez moi.

                    Si je test avec temps_act = 0;

                    j'arrive à la même date... alors il y a probablement quelque chose de différent que la conversion ne prend pas en compte... le changement à l'heure d'été ou simplement les minutes et les secondes... je ne sais pas. Je vérifie.


                    EDIT :

                    Voilà ! Je devais caster en double le timestamp et non pas le timetamp / 86400. Mes excuses... :-°

                    inline double round( double d )
                    {
                        return std::floor( d + 0.5 );
                    }
                    
                    inline time_t ConvertTDateTime( double datetime ) 
                    {
                        return static_cast<time_t>( round( (datetime - 25569.0) * 86400.0 ) );
                    }
                    
                    inline double MakeTDateTime(time_t timestamp) 
                    {
                        return static_cast<double>( timestamp ) / 86400.0 + 25569.0;
                    }
                    


                    Pour la lecture du fichier tu ne peux pas interpréter le double delphi en entier et le caster en double C++... Enfin... je ne sais pas comment fonctionne les doubles en delphi et si c'est différent du C++
                    • Partager sur Facebook
                    • Partager sur Twitter
                      12 août 2008 à 17:44:49

                      Citation : MatteX

                      j'arrive à la même date... alors il y a probablement quelque chose de différent que la conversion ne prend pas en compte... le changement à l'heure d'été ou simplement les minutes et les secondes... je ne sais pas. Je vérifie.



                      Merci à toi ! :)
                      Je sais pas combien de temps il me faudrait pour voire tout ca ... mais je pense que jusque décembre :lol:
                      • Partager sur Facebook
                      • Partager sur Twitter
                        12 août 2008 à 18:40:55

                        Oups, j'avais commencé à éditer il y a 2 heures mais j'ai été pris avec autre chose... tu peux regarder la solution dans mon message précédent
                        • Partager sur Facebook
                        • Partager sur Twitter
                          12 août 2008 à 19:41:08

                          Citation : MatteX

                          Voilà ! Je devais caster en double le timestamp et non pas le timetamp / 86400. Mes excuses... :-°



                          Bon aller... je t'excuse.. mais c'est parcque je suis dans un bon jour ! :p
                          Merci à toi !!

                          Ca fonctionne parfaitement maintenant !!
                          Je n'ai plus qu'a trouver comment bien extraire cette valeur ....

                          Ben à la limite... Un double, je suppose que l'on peut le stocker en Hexa. Comment le lire sans parlé de Delphi ou C++ ?


                          Edit: C'est bon, ca fonctionne !
                          Le problème venait du fais que le développeur du soft qui coupe les fichiers s'est planté dans sa spec.

                          Merci à toi MatteX !!
                          Tu m'as retiré un sacré épine du pied !! ^^
                          • Partager sur Facebook
                          • Partager sur Twitter

                          Convertir un Long en Date

                          × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                          × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                          • Editeur
                          • Markdown