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

Algorithmes et structures de données Discussion :

Calcul de durée entre deux dates en années, mois, jours, heures, minutes, secondes et reste


Sujet :

Algorithmes et structures de données

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Invité
    Invité(e)
    Par défaut Calcul de durée entre deux dates en années, mois, jours, heures, minutes, secondes et reste
    Bonjour,
    J'essaie de mettre au point une fonction ou procédure pour calculer la durée entre deux date.

    J'espère que le code est admis ici parce que je serais incapable de produire autre chose.

    Ma procédure écrite avec le langage Ada prend 9 paramètre dont deux sont les dates à comparer, la date de début doit être inférieur à la date de fin.
    Celle- ci, doit retourner le nombre d'années, de mois de jour, et les heures avec les minutes les secondes et le reste (les millisecondes).

    Pour le moment, je souhaite faire expertiser pour avoir votre avis une version qui ne calcule que les années les mois et les jours.

    Avec les calculs sur les année bissextiles j'arrive à des truc rigolo comme 1 an 11 mois et 33 jours C'est pourquoi j'ai un doute.

    J'aimerais avoir votre avis.

    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
    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
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    with Ada.Integer_Text_Io;
    with Ada.Text_Io;
    with Ada.Calendar;
    use Ada.Calendar;
    with Ada.Calendar.Time_Zones;
    with Ada.Calendar.Formatting;
    with Ada.Calendar.Arithmetic;
    use Ada.Calendar.Arithmetic;
    use Ada;
    procedure Test_Elapsed is
     
       function Is_Leap_Year (Year : Integer) return Boolean is
       begin
          return (Year rem 4 = 0) and ((Year rem 100 /= 0) or (Year rem 16 = 0));
       end Is_Leap_Year;
     
       pragma Inline (Is_Leap_Year);
     
       Days_Months_Count : constant array (Month_Number) of Day_Number := (31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
     
       procedure Difference_In_Years(Top_Date : in Time;
                                     Bot_Date : in Time;
                                     Years    : out Natural;
                                     Months   : out Natural;
                                     Days     : out Natural;
                                     Houres    : out Natural;
                                     Minutes  : out Natural;
                                     Second : out Natural;
                                     Rest     : out Natural) is      
     
     
          Top_Days_Total    : Day_Count := 0;
          Top_Seconds_Total : Duration := 0.0;
          Top_Leap_Seconds  : Leap_Seconds_Count := 0;            
     
          Bot_Days_Total    : Day_Count := 0;
          Bot_Seconds_Total : Duration := 0.0;
          Bot_Leap_Seconds  : Leap_Seconds_Count := 0;            
     
          Top_Seconds : Day_Duration := Seconds(Top_Date);
          Bot_Seconds : Day_Duration := Seconds(Bot_Date);
          Top_Day     : Day_Number := Day(Top_Date);
          Bot_Day     : Day_Number := Day(Bot_Date);
          Top_Year    : Year_Number := Year(Top_Date);
          Bot_Year    : Year_Number := Year(Bot_Date);
          Top_Month   : Month_Number := Month(Top_Date);
          Bot_Month   : Month_Number := Month(Bot_Date);
     
     
       begin
     
          if Top_Date > Bot_Date then
             raise Constraint_Error;
          end if;
     
          Years    := 0;
          Months   := 0;
          Days     := 0;
          Houres   := 0;
          Minutes  := 0;
          Second   := 0;
          Rest     := 0;
     
          if Top_Year < Bot_Year then                           
             Years := (Bot_Year - 1) - (Top_Year);                  
             if Bot_Month - 1 >= Top_Month then
     
                Months := 12 - ((Bot_Month) - (Top_Month));
             else
     
                Months := 12 - ((Top_Month) - (Bot_Month - 1));
             end if;
          else         
     
             Months := (Bot_Month - Top_Month);
          end if;      
     
          if Bot_Day - 1 > Top_Day then         
             if Top_Month > 1 then            
                Days := (Days_Months_Count(Top_Month-1) - Top_Day) + Bot_Day;
     
             else
                Days := (Days_Months_Count(Days_Months_Count'last) - Top_Day) + Bot_Day;
     
             end if;         
          elsif Bot_Day - 1 < Top_Day then
             if Top_Month < 12 then
     
                Days := (Days_Months_Count(Top_Month) - Top_Day) + (Bot_Day - 1);
                if Days = Days_Months_Count(Top_Month + 1) then
                   Text_Io.Put_Line("3.1");
                   Days := 0;
                end if;
             else
     
                Days := (Days_Months_Count(Days_Months_Count'first) - Top_Day) + (Bot_Day - 1);
                if Days = Days_Months_Count(1) then
     
                   Days := 0;
                end if;
             end if;         
          else
     
             if Is_Leap_Year(Bot_Year) then            
                if Bot_Month = 2 then               
                   if Bot_Day > Days_Months_Count(2) then
     
                      Days := 1;               
                   end if;
                else
                   if Top_Month > 1 then            
                      Days := (Days_Months_Count(Top_Month-1) - Top_Day) + Bot_Day - 1;
     
                   else
                      Days := (Days_Months_Count(Days_Months_Count'last) - Top_Day) + Bot_Day - 1;
     
                   end if;
                end if;
             end if;
          end if;      
     
       end Difference_In_Years;
     
     
     
       Top_Date : Time := Time_Of(2010, 01, 27, 18000.0);
       Bot_Date : Time := Time_Of(2012, 02, 29, 18000.0);
       Years    : Natural := 0;
       Months   : Natural := 0;
       Days     : Natural := 0;
       Houres    : Natural := 0;
       Minutes  : Natural := 0;
       Second : Natural := 0;
       Rest     : Natural := 0;
     
     
    begin
       Difference_In_Years(Top_Date,
                           Bot_Date,
                           Years,
                           Months,
                           Days,
                           Houres,
                           Minutes,
                           Second,
                           Rest);
       Text_Io.Put(Natural'Image(Years)(2..Natural'Image(Years)'Last));
       Text_Io.Put("y, ");
       Text_Io.Put(Natural'Image(Months)(2..Natural'Image(Months)'last));
       Text_Io.Put("m, ");
       Text_Io.Put(Natural'Image(Days)(2..Natural'Image(Days)'last));
       Text_Io.Put("d, ");
       Text_Io.Put(Natural'Image(Houres)(2..Natural'Image(Houres)'last));
       Text_Io.Put(':');
       Text_Io.Put(Natural'Image(minutes)(2..Natural'Image(Minutes)'last));
       Text_Io.Put(':');
       Text_Io.Put(Natural'Image(Second)(2..Natural'Image(Second)'last));
       Text_Io.Put('.');
       Text_Io.Put(Natural'Image(Rest)(2..Natural'Image(Rest)'last));
       Text_Io.Put('s' & Character'Val(10));  
    end Test_Elapsed;
    Ca programme affiche :

    1y, 11m, 33d, 0:0:0.0s

    Merci pour vos réponses.
    Dernière modification par Invité ; 01/02/2015 à 18h28. Motif: il manquait les données d'initialisation dans le code.

  2. #2
    Rédacteur/Modérateur

    Homme Profil pro
    Ingénieur qualité méthodes
    Inscrit en
    Décembre 2013
    Messages
    4 216
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur qualité méthodes
    Secteur : Conseil

    Informations forums :
    Inscription : Décembre 2013
    Messages : 4 216
    Par défaut
    J'utilise le langage Windev... mais tu devrais pourvoir traduire facilement ce code :

    Fonction principale :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    d1, d2  est une Date
    d1 = "20110127"
    d2 = "20120229"
     
    nb_a, nb_m, nb_j est un entier
    (nb_a, nb_m, nb_j) = fdiff(d1,d2)
    ch est une chaîne
    ch = " %1 années %2 mois %3 jours"
    ch = ChaîneConstruit(ch, nb_a, nb_m, nb_j)
    Info(ch)
    fonction de calcul du nombre d'années / mois / jours :
    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
     
    PROCEDURE fdiff(d1,d2)
    na, nm, nj est un entier
     
    a1, m1, j1, a2, m2, j2 est un entier
    a1 = d1..Année
    m1 = d1..Mois
    j1 = d1..Jour
    a2 = d2..Année
    m2 = d2..Mois
    j2 = d2..Jour
     
    na = ( a2-a1-1)
    SI m2 > m1 _OU_ ( m2= m1 _ET_ j2>= j1) ALORS 
    	na++
    SINON
    	m2 += 12
    FIN
    nm = m2-m1-1
    SI j2>= j1 ALORS 
    	nm++
    	nj = j2-j1
    SINON
    	nj = dernjour_moisprecedent( a2, m2, j2 ) - j1
    	SI nj < 0 ALORS nj = 0
    	nj += j2
    FIN
    RENVOYER ( na, nm, nj )
    Et enfin la procédure pour calculer le nombre de jours du mois précédent, en prenant en compte les années bissextiles :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    PROCEDURE dernjour_moisprecedent(a2,m2,j2)
     
    t est un tableau de 12 entiers
    t[1] = 31 ; t[2]  =  28 ; t[3]= 31 ; t[4] = 30 ; t[5] = 31 ; t[6] = 30 ; t[7] = 31 ; t[8] = 31 ; t[9] = 30 ; t[10] = 31 ; t[11] = 30 ; t[12] = 31
    SI m2 = 1 RENVOYER 31     //  si janvier, le mois précédent est décembre.
    SI m2<>3 ALORS RENVOYER t[m2-1]  // Si différent de mars, pas de problème. 
     
    // Année bissextile ?
    SI modulo(a2,4) <> 0 ALORS RENVOYER 28 
    SI modulo(a2,100) = 0 _ET_ modulo(a2, 400) <> 0 ALORS RENVOYER 28 
    RENVOYER 29

  3. #3
    Invité
    Invité(e)
    Par défaut
    Merci pour le code.

  4. #4
    Invité
    Invité(e)
    Par défaut
    Bonjour, (je suis réveillé).

    Donc, j'ai translaté le code, mais j'ai un problème.

    A la ligne 125, je me trouve avec un nombre mois négatif dès le premier test qui est un test entre deux date identique mais même en chageant l'année de début c'est la même erreur me semble t- il.

    Voici mon code complet (normalement compilable) :

    Code Ada : 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
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
     
    with Ada.Integer_Text_Io;
    with Ada.Text_Io;
    with Ada.Calendar;
    use Ada.Calendar;
    with Ada.Calendar.Time_Zones;
    use Ada.Calendar.Time_Zones;
    with Ada.Calendar.Formatting;
    use Ada.Calendar;
    with Ada.Calendar.Arithmetic;
    use Ada.Calendar.Arithmetic;
    use Ada;
    procedure Elapsed_Years is
     
       procedure Print_Elapsed(Top_Date : in Time;
                               Bot_Date : in Time;
                               Years    : in Natural;
                               Months   : in Natural;
                               Days     : in Natural;
                               Houres   : in Natural;
                               Minutes  : in Natural;
                               Second   : in Natural;
                               Rest     : in Natural) is
       begin
          Text_Io.Put("Pour l'interval entre le " &
                        Formatting.Image(Top_Date, False, UTC_Time_Offset(Top_Date)) & " et le " &
                        Formatting.Image(Bot_Date, False, UTC_Time_Offset(Bot_Date)) & " le temps à écoulé ");
          Text_Io.Put(Natural'Image(Years)(2..Natural'Image(Years)'Last));
          Text_Io.Put("y, ");
          Text_Io.Put(Natural'Image(Months)(2..Natural'Image(Months)'last));
          Text_Io.Put("m, ");
          Text_Io.Put(Natural'Image(Days)(2..Natural'Image(Days)'last));
          Text_Io.Put("d");
       end Print_Elapsed;
     
     
     
       function Is_Leap_Year (Year : Integer) return Boolean is
       begin
          return (Year rem 4 = 0) and ((Year rem 100 /= 0) or (Year rem 16 = 0));
       end Is_Leap_Year;
     
       pragma Inline (Is_Leap_Year);
     
       Days_Months_Count : constant array (Month_Number) of Day_Number := (31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
     
       procedure Difference_In_Years(Top_Date : in Time;
                                     Bot_Date : in Time;
                                     Years    : out Natural;
                                     Months   : out Natural;
                                     Days     : out Natural;
                                     Houres   : out Natural;
                                     Minutes  : out Natural;
                                     Second   : out Natural;
                                     Rest     : out Natural) is
     
     
     
          function Last_Days(Years , Months, Days : in Natural) return Natural is
          begin
     
             if Months = 1 then
                return Days_Months_Count(12);
             end if;
     
             if Months /= 3 then
                return Days_Months_Count(Months-1);
             end if;
     
             if Is_Leap_Year(Years) then
                return Days_Months_Count(2) + 1;
             else
                return Days_Months_Count(2);
             end if;
          end Last_Days;
     
     
          Top_Days_Total    : Day_Count := 0;
          Top_Seconds_Total : Duration := 0.0;
          Top_Leap_Seconds  : Leap_Seconds_Count := 0;
     
          Bot_Days_Total    : Day_Count := 0;
          Bot_Seconds_Total : Duration := 0.0;
          Bot_Leap_Seconds  : Leap_Seconds_Count := 0;
          Top_Seconds : Day_Duration := Seconds(Top_Date);
          Bot_Seconds : Day_Duration := Seconds(Bot_Date);
          Top_Day     : Day_Number := Day(Top_Date);
          Bot_Day     : Day_Number := Day(Bot_Date);
          Top_Year    : Year_Number := Year(Top_Date);
          Bot_Year    : Year_Number := Year(Bot_Date);
          Top_Month   : Month_Number := Month(Top_Date);
          Bot_Month   : Month_Number := Month(Bot_Date);
     
          Years_Number  : Integer := 0;
          Months_Number : Integer := 0;
          Days_Number   : Integer := 0;
     
       begin
     
          if Top_Date > Bot_Date then
             raise Constraint_Error;
          end if;
     
          Years    := 0;
          Months   := 0;
          Days     := 0;
          Houres   := 0;
          Minutes  := 0;
          Second   := 0;
          Rest     := 0;
     
          Years_Number := (Bot_Year - Top_Year - 1);
     
     
          if (Bot_Month > Top_Month) or ((Bot_Month = Top_Month) and (Bot_Day >= Top_Day)) then
     
             Years := Years_Number + 1;
     
          else
     
             Months_Number := Bot_Month + 12;
     
             Years := Years_Number;
          end if;
     
          Months_Number := Months_Number - Top_Month - 1;
     
          if Bot_Day >= Top_Day then
     
             Months := Months_Number + 1;
     
             Days := Bot_Day - Top_Day;
          else
     
             Days_Number := Last_Days (Bot_Year, Months_Number, Bot_Day) - Top_Day;
     
             if Days_Number < 0 then
               Days := Days_Number + Bot_Day;
     
             end if;
     
             Months := Months_Number;
          end if;
       end Difference_In_Years;
     
     
       Top_Date : Time := Time_Of(2009, 03, 28, 18000.0);
       Bot_Date : Time := Time_Of(2011, 05, 30, 18000.0);
       Years    : Natural := 0;
       Months   : Natural := 0;
       Days     : Natural := 0;
       Houres    : Natural := 0;
       Minutes  : Natural := 0;
       Second : Natural := 0;
       Rest     : Natural := 0;
     
     
       type Elapsed_Type is
          record
             Top_Date : Time;
             Bot_Date : Time;
          end record;
     
       Test_Set : array (1..14) of Elapsed_Type:=
         ((Time_Of(2009, 05, 15, 0.0), Time_Of(2009, 05, 15, 0.0)),
          (Time_Of(2009, 04, 15, 0.0), Time_Of(2011, 05, 1, 0.0)),
          (Time_Of(2009, 05, 15, 0.0), Time_Of(2011, 04, 1, 0.0)),
          (Time_Of(2009, 04, 1, 0.0), Time_Of(2011, 05, 15, 0.0)),
          (Time_Of(2012, 02, 1, 0.0), Time_Of(2015, 03, 1, 0.0)),
          (Time_Of(2012, 02, 1, 0.0), Time_Of(2015, 01, 31, 0.0)),
          (Time_Of(2012, 02, 29, 0.0), Time_Of(2015, 01, 31, 0.0)),
          (Time_Of(2012, 03, 1, 0.0), Time_Of(2015, 02, 28, 0.0)),
          (Time_Of(2012, 03, 1, 0.0), Time_Of(2016, 02, 29, 0.0)),
          (Time_Of(2012, 02, 28, 0.0), Time_Of(2014, 12, 31, 0.0)),
          (Time_Of(2012, 02, 29, 0.0), Time_Of(2015, 1, 1, 0.0)),
          (Time_Of(2012, 02, 28, 0.0), Time_Of(2012, 02, 29, 0.0)),
          (Time_Of(2013, 02, 28, 0.0), Time_Of(2015, 3, 1, 0.0)),
          (Time_Of(2012, 02, 2, 0.0), Time_Of(2015, 3, 1, 0.0)));
     
    begin
       for Elapsed in Test_Set'Range loop
          Difference_In_Years(Test_Set(Elapsed).Top_Date,
                              Test_Set(Elapsed).Bot_Date,
                              Years,
                              Months,
                              Days,
                              Houres,
                              Minutes,
                              Second,
                              Rest);
          Print_Elapsed(Test_Set(Elapsed).Top_Date,
                        Test_Set(Elapsed).Bot_Date,
                        Years,
                        Months,
                        Days,
                        Houres,
                        Minutes,
                        Second,
                       Rest);
          Text_Io.New_Line;
       end loop;
     
    end Elapsed_Years;


    Il y a un petit jeu supplémentaire entre les entier et les naturel parce que ma procédure retourne des naturel alors que j'ai bien compris qu'on pouvais obtenir des jours négatifs avec cet algo, mais pas les mois, ou j'ai pas compris, en tout cas j'ai un problème.

    Merci pour votre aide.

  5. #5
    Invité
    Invité(e)
    Par défaut
    Yep !


    J'ai trouvé deux choses.

    La première c'est qu'il manque l'affectation de Bot_Month dans le premier "if" à Monts_Number.

    La seconde est dans la fonction derniers_jour du mois précédant, le second if devrait me semble t- il faire l'objet d'en elsif. En tout cas avec Ada.

    Je vais analyser les résultat maintenant que ça passe et je reviens éventuellement.

    En tout cas merci encore pour le code. j'étais en galère pas possible.

    Merci.

    Et même une troisième, j'ai oublié entre parenthèse le Top_Month - 1 :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Months_Number := Months_Number - (Top_Month - 1);

  6. #6
    Invité
    Invité(e)
    Par défaut
    J'espère avoir ici apporté des corrections plutôt que des erreurs.

    J'ai cherché, euh une vingtaine de minutes heure peut-être, voici le corps de la procédure, avec les corrections des corrections.

    Code Ada : 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
     
       begin
     
          if Top_Date > Bot_Date then
             raise Constraint_Error;
          end if;
     
          Years    := 0;
          Months   := 0;
          Days     := 0;
          Houres   := 0;
          Minutes  := 0;
          Second   := 0;
          Rest     := 0;
     
          Years_Number := (Bot_Year - Top_Year - 1);
     
          if (Bot_Month > Top_Month) or ((Bot_Month = Top_Month) and (Bot_Day >= Top_Day)) then         
     
             Years_Number := Years_Number + 1;
             Months_Number := Bot_Month;
          else         
             Months_Number := Bot_Month + 12;
          end if;
     
     
          Months_Number := (Months_Number - Top_Month - 1);
     
          if Bot_Day >= Top_Day then
     
             Months_Number := Months_Number + 1;
             Days_Number := Bot_Day - Top_Day;
          else
             Days_Number := Last_Days (Bot_Year, Months_Number + 1) - Top_Day;                           
             if Days_Number < 0 then
                Days_Number := Days_Number + Bot_Day;
             end if;                  
          end if;
          Days := Days_Number;
          Months := Months_Number;
          Years := Years_Number;
       end Difference_In_Years;

    Alors je ne sais pas ou tu en est avec votre procédure Windev, mais c'est sensiblement différent.
    Est- ce du au priorités des opérateur ?

    Voici le résultat, si vous trouvez une erreur merci de me le faire savoir.

    Pour l'interval entre le 2009-05-15 et le 2009-05-15 le temps à écoulé 0y, 0m, 0d,
    Pour l'interval entre le 2009-04-15 et le 2011-05-01 le temps à écoulé 2y, 0m, 16d,
    Pour l'interval entre le 2009-05-15 et le 2011-04-01 le temps à écoulé 1y, 10m, 16d,
    Pour l'interval entre le 2009-04-01 et le 2011-05-15 le temps à écoulé 2y, 1m, 14d,
    Pour l'interval entre le 2012-02-01 et le 2015-03-01 le temps à écoulé 3y, 1m, 0d,
    Pour l'interval entre le 2012-02-01 et le 2015-01-31 le temps à écoulé 2y, 11m, 30d,
    Pour l'interval entre le 2012-02-29 et le 2015-01-31 le temps à écoulé 2y, 11m, 2d,
    Pour l'interval entre le 2012-03-01 et le 2015-02-28 le temps à écoulé 2y, 11m, 27d,
    Pour l'interval entre le 2012-03-01 et le 2016-02-29 le temps à écoulé 3y, 11m, 28d,
    Pour l'interval entre le 2012-02-28 et le 2014-12-31 le temps à écoulé 2y, 10m, 3d,
    Pour l'interval entre le 2012-02-29 et le 2015-01-01 le temps à écoulé 2y, 10m, 2d,
    Pour l'interval entre le 2012-02-28 et le 2012-02-29 le temps à écoulé 0y, 0m, 1d,
    Pour l'interval entre le 2013-02-28 et le 2015-03-01 le temps à écoulé 2y, 0m, 3d,
    Pour l'interval entre le 2012-02-02 et le 2015-03-01 le temps à écoulé 3y, 0m, 29d,

  7. #7
    Membre Expert Avatar de DonQuiche
    Inscrit en
    Septembre 2010
    Messages
    2 741
    Détails du profil
    Informations forums :
    Inscription : Septembre 2010
    Messages : 2 741
    Par défaut
    Citation Envoyé par jovalise Voir le message
    Celle- ci, doit retourner le nombre d'années, de mois de jour, et les heures avec les minutes les secondes et le reste (les millisecondes).
    Citation Envoyé par jovalise Voir le message
    Je comprends, a priori je n'ai pas besoin de ces nuances.
    Tu as besoin d'une précision à la milliseconde et pourtant tu n'as pas besoin de prendre en compte les changements d'heures et les secondes intercalaires ?

    Ou bien n'as-tu au final besoin que d'une précision au jour près ? Mais même dans ce cas, est-il acceptable que ta durée puisse diminuer ? Par exemple une échéance à 2h10 du matin pourrait se produire une fois, incrémentant le nb de jours, avant de diminuer lors du changement d'heure. Plus généralement une date à 2h10 du matin désigne t-elle la première ou la seconde occurrence de cette heure-ci ?

    Tu es bien sûr de ne pas avoir besoin de ces nuances ?

  8. #8
    Invité
    Invité(e)
    Par défaut
    Bonjour, ....


    A priori oui.

    Je suis en UTC. Je ne considère donc aucun changement d'heure.

  9. #9
    Membre Expert Avatar de DonQuiche
    Inscrit en
    Septembre 2010
    Messages
    2 741
    Détails du profil
    Informations forums :
    Inscription : Septembre 2010
    Messages : 2 741
    Par défaut
    Citation Envoyé par jovalise Voir le message
    Je suis en UTC. Je ne considère donc aucun changement d'heure.
    Ok. Et tu peux également te permettre d'accumuler une erreur de quelques secondes par décennie sur la durée physique du fait des secondes intercalaires ?

    Par ailleurs es-tu certain d'avoir des dates UTC correctes ? Si un utilisateur stipule le "1er décembre à 9h00", sous-entendu dans le fuseau local (non-UTC), le 1er décembre se trouvera dans une autre chronologie qu'aujourd'hui (du fait du chgt d'heure). La conversion vers UTC sera t-elle correcte ?

    Note d'ailleurs qu'il est impossible d'obtenir une conversion local -> UTC fiable pour une date future : des changements légaux peuvent intervenir. Tout comme il est impossible de prédire le nombre de secondes intercalaires entre une date UTC passée et une date UTC future.

  10. #10
    Invité
    Invité(e)
    Par défaut
    Non plus.
    C'est vraiment minimal comme besoin.
    De plus je pense qu'il faudrait, au cas ou je calcule ces secondes, les calculer également au moment de fixer le compte à reboure.

    Si il est 00:00:00.0 et que je fixe un délais de 00:00:01.0 et que pendant cette seconde j'en ajoute une, il faut que j'ajoute une seconde à mon délais pour conserver 1 seconde de delais.

    Donc non, ça m'intéresse pas plus que ça.


    Note d'ailleurs, qu je code avec Ada, et Ada défini une journée avec 86400 seconde au milième près.

    Si les jours devais diminuer au augmenter, Ada le spécifierais, et je n'ai pas à m'en préocuper mais je vois à la réflexion que j'ai un litéral qui fait référence à cette valeur, je vais corriger.

  11. #11
    Membre Expert Avatar de DonQuiche
    Inscrit en
    Septembre 2010
    Messages
    2 741
    Détails du profil
    Informations forums :
    Inscription : Septembre 2010
    Messages : 2 741
    Par défaut
    Citation Envoyé par jovalise Voir le message
    De plus je pense qu'il faudrait, au cas ou je calcule ces secondes, les calculer également au moment de fixer le compte à reboure.
    Tu ne pourrais pas : les secondes intercalaires futures sont inconnues. On ne connaît que celles du passé.

    Pour un compte à rebours dont on aurait spécifié exactement la durée la façon propre (mais peut-être inutile dans ton cas) serait de stocker la date de départ et la durée requise.

    A chaque tic on calculerait la durée écoulée entre maintenant et la date de départ, en utilisant une base de données des secondes intercalaires (ou le service temporel de l'OS, qui garde déjà ces données). Puis on calculerait la différence entre le temps écoulé et la durée spécifiée.


    Note d'ailleurs, qu je code avec Ada, et Ada défini une journée avec 86400 seconde au milième près.

    Si les jours devais diminuer au augmenter, Ada le spécifierais
    Mais certains jours durent exceptionnellement 86401s. Comme le 30 juin dernier. Ce sont des secondes qui sont ajoutés au besoin pour prendre en compte les variations imprévisibles de la rotation terrestre. C'est le principe des secondes intercalaires. Et à l'avenir certains jours dureront peut-être 86402s ou 86399s, on ne peut pas savoir.

Discussions similaires

  1. Réponses: 5
    Dernier message: 24/08/2015, 16h46
  2. Réponses: 14
    Dernier message: 11/12/2013, 14h59
  3. Réponses: 1
    Dernier message: 30/04/2008, 11h00
  4. Réponses: 10
    Dernier message: 14/12/2007, 14h13

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