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

VB.NET Discussion :

Différence entre 2 dates en années/mois/jours


Sujet :

VB.NET

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre Expert Avatar de _Ez3kiel
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2013
    Messages
    836
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Janvier 2013
    Messages : 836
    Par défaut Différence entre 2 dates en années/mois/jours
    Bonjour à tous,

    J'essaye de calculer la différence entre 2 dates, en 3 unités de mesure (Année/Mois/Jours)

    Un exemple plus parlant :

    La différence entre 01/01/2012 et 02/02/2013 est de 1 an, 1 mois, et 1 jour.

    J'ai essayé plusieurs méthodes, la dernière en date étant :

    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
            Dim datedebut As Date = New Date(1992, 1, 28)
            Dim datefin As Date = New Date(2009, 9, 1)
     
            Dim resultatAnnee As Decimal
            Dim resultatMois As Decimal
            Dim resultatJours As Decimal
     
     
            Dim totaljours As Long
            Dim totalmois As Long
            Dim totalannee As Long
     
     
     
            totaljours = DateDiff(DateInterval.DayOfYear, datedebut, datefin)
            totalmois = DateDiff(DateInterval.Month, datedebut, datefin)
            totalannee = DateDiff(DateInterval.Year, datedebut, datefin)
     
     
            resultatAnnee = totalannee
            resultatMois = totalmois - (totalannee * 12)
            resultatJours = Math.Round(CDec((totaljours - (totalannee * 365.2425) - (resultatMois * 30.41666666667))))
     
     
            MsgBox(resultatAnnee.ToString & " ans " & resultatMois.ToString & " mois " & resultatJours.ToString & " jours") 'Retourne 17 ans, 8mois et -26 jours ...
    Qui aurait pu convenir sauf dans le cas où le jour de Date1 est en fin de mois et celui de Date2 en début de mois ...


    Est-ce quelqu'un aurait une petite idée ?
    En vous remerciant d'avance !

  2. #2
    Membre expérimenté
    Avatar de Kropernic
    Homme Profil pro
    Analyste / Programmeur / DBA
    Inscrit en
    Juillet 2006
    Messages
    3 932
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : Belgique

    Informations professionnelles :
    Activité : Analyste / Programmeur / DBA
    Secteur : Distribution

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 932
    Par défaut
    Pourquoi ne pas partir du résultat fournit par la fonction Subtract d'une variable de type Date ?

    Cette fonction renvoyant un timespan, tu as donc le nombre de jours de différence (je ne tiens pas compte des heures(, minutes, etc.) vu que tu ne cherches à comparer que des dates) et tu peux facilement** recalculer ton nombre de mois et d'années.

    **Car d'après ton code, tu as des valeurs précises pour un mois et une année.

    Mais d'un point de vue purement théorique/mathématique, quel est le nombre de jours d'un mois ? 28, 29, 30 ou 31, une moyenne ? Pour l'année, c'est un peu moins grave mais la question est similaire.

  3. #3
    Membre Expert Avatar de _Ez3kiel
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2013
    Messages
    836
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Janvier 2013
    Messages : 836
    Par défaut
    Je ne vois pas trop où tu veux en venir ... Substract m'a l'air d'être l'équivalent de la fonction DateDiff que j'utilise dans mon code.

    J'en arrive au même point, c'est à dire 6426 jours.

    C'est la notion de calcul d'après qui me dérange, car selon le calcul, on pourrait partir des moyennes que j'utilise (365.2425 jours/an & 30.41666666667 jours/mois)


    Mais tu pointes le doigt sur ce qui me dérange, c'est que ça se base sur une moyenne, et le résultat n'est donc pas -vraiment- exact ... Du 28 février au 02 mars il y a 3 jours (inclusif), mais du 28 mars au 02 avril, il y a 6 jours.


    Je bloque car j'ai l'impression de ne pas avoir la bonne logique...

    Je réitère mon exemple pour bien vous faire comprendre que je ne cherche pas à avoir la différence en une seule unité de mesure, mais en 3 unités qui se complémentent.

    La différence entre 01/01/2012 et 02/02/2013 est de 1 an, 1 mois, et 1 jour.

  4. #4
    Membre expérimenté
    Avatar de Kropernic
    Homme Profil pro
    Analyste / Programmeur / DBA
    Inscrit en
    Juillet 2006
    Messages
    3 932
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : Belgique

    Informations professionnelles :
    Activité : Analyste / Programmeur / DBA
    Secteur : Distribution

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 932
    Par défaut
    Je pense que le problème vient surtout du fait que, pour moi, un mois ou une année ne sont pas des unités de mesures (du moins dans ce cas) car leur taille varie.

    Une unité de mesure est une référence et de ce fait se doit d'être constante.

    T'imagines le bordel si, pour une raison x ou y, le mètre n'avait pas la même taille partout ?

    Bref, pour moi, pour calculer l'écart entre deux dates, l'unité est le jour (ou une de ces portions).

    Après, dans certains, mois et année peuvent devenir des unités de mesures mais pas pour mesurer l'écart entre deux dates.
    Si on veut mesurer le nombre de mois entre Mars 2017 et Mai 2027, alors là oui, le mois peut être une unité de mesure acceptable. Voir même l'année car, à moins d'une réforme d'ici là, le nombre de mois dans une année est constant.

  5. #5
    Membre Expert Avatar de _Ez3kiel
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2013
    Messages
    836
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Janvier 2013
    Messages : 836
    Par défaut
    @Kropernic: Oui il faut une unité fiable et constante, mais je trouvais pas laquelle. Car comme tu l'as dit, il y n'avait que les mois. Les jours étaient relatifs au mois, et mélangé aux années bissextiles je me perdais dans mes calculs.

    @shayw: Oui j'avais remarqué ça aussi, c'est pour ça que j'étais parti sur la base "jour" pour les calculs.


    @Tomlev: Wow ... Je suis époustouflé, j'aurais pu chercher encore longtemps ! J'ai jamais songé à une approche de cette manière d'un calcul de date ...

    Ton code est fonctionnel à merveille, j'ai pas encore trouvé de limites, j'ai testé tous les cas les plus limites que je pourrais avoir, années bissextiles comprises, mais avec un algo comme ça je vois pas la faille ...

    J'ai bien décortiqué et compris dans l'ensemble le calcul, hormis une partie pour laquelle j'aimerais encore des détails, si ce n'est pas trop abusé.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    If days >= daysInMonth Then
                days = daysInMonth - 100 + days
    End If
    Et

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    If months >= 12 Then
                months = 12 - 100 + months
    End If
    Merci encore.

    Ci-joint le rendu Vb.NET avec le code un peu plus décortiqué (pour la lisibilité), et je ne me suis pas embêté à faire une classe uniquement pour ça, c'était vraiment pour un cas particulier mais sur lequel je butais.

    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
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            Dim final As Long() = DateDiffAnneeMoisJour(Date.Parse("28/02/1994"), Date.Parse("01/09/1995"))
     
            MsgBox(final(0) & " ans " & final(1) & " mois " & final(2) & " jours") 'retourne 1 an 6 mois 1 jour
        End Sub
     
        ''' <summary>
        ''' Retourne l'écart entre 2 dates décomposé en année mois et jour
        ''' </summary>
        ''' <param name="dateDebut">Date de début</param>
        ''' <param name="dateFin">Date de fin</param>
        ''' <returns>Tableau de long -> 0:Années // 1:Mois // 2:Jours </returns>
        Public Shared Function DateDiffAnneeMoisJour(dateDebut As DateTime, dateFin As DateTime) As Long()
            Dim ix As Integer
            Dim iy As Integer
            Dim diff As Integer
            Dim sign As Integer
            Dim s As String
            Dim years As Integer
            Dim months As Integer
            Dim days As Integer
            Dim daysInMonth As Integer
     
            ix = Integer.Parse(dateDebut.ToString("yyyyMMdd"))
            iy = Integer.Parse(dateFin.ToString("yyyyMMdd"))
     
            diff = iy - ix
     
            sign = Math.Sign(diff)
     
            s = Math.Abs(diff).ToString("D8")
     
            years = Integer.Parse(s.Substring(0, 4))
            months = Integer.Parse(s.Substring(4, 2))
     
     
            If months >= 12 Then
                months = 12 - 100 + months
            End If
     
            days = Integer.Parse(s.Substring(6, 2))
            daysInMonth = DateTime.DaysInMonth(dateDebut.Year, dateDebut.Month)
     
     
            If days >= daysInMonth Then
                days = daysInMonth - 100 + days
            End If
     
            Return {sign * years, sign * months, sign * days}
        End Function

  6. #6
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Par défaut
    Citation Envoyé par _Ez3kiel Voir le message
    @Tomlev: Wow ... Je suis époustouflé, j'aurais pu chercher encore longtemps ! J'ai jamais songé à une approche de cette manière d'un calcul de date ...
    A vrai dire je ne l'ai pas inventé, je me suis inspiré de ça : http://stackoverflow.com/a/11942/98713
    Ca marche tout seul pour l'année, mais pour le mois et le jour il faut ruser un peu...

    Citation Envoyé par _Ez3kiel Voir le message
    J'ai bien décortiqué et compris dans l'ensemble le calcul, hormis une partie pour laquelle j'aimerais encore des détails, si ce n'est pas trop abusé.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    If days >= daysInMonth Then
                days = daysInMonth - 100 + days
    End If
    Et

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    If months >= 12 Then
                months = 12 - 100 + months
    End If
    Bah en fait, si par exemple les dates sont le 10/09/2012 et le 10/08/2013, ça fait 20130810 - 20120910 = 00009900, soit 0 années, 99 mois et 0 jours... évidemment, 99 fois ça n'a pas de sens : il y a 12 mois, pas 100. Donc en fait ce 99 correspond à 11 mois, d'où la correction

    Le principe est à peu près le même pour les jours : je me base sur le nombre de jours dans le mois. Par contre je ne suis pas sûr d'utiliser le bon mois

  7. #7
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Par défaut
    Tu peux faire quelque chose comme ça :

    Code C# : 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
        struct DateSpan
        {
            private readonly int _years;
            private readonly int _months;
            private readonly int _days;
     
            public DateSpan(int years, int months, int days)
            {
                _years = years;
                _months = months;
                _days = days;
            }
     
            public int Years
            {
                get { return _years; }
            }
     
            public int Months
            {
                get { return _months; }
            }
     
            public int Days
            {
                get { return _days; }
            }
     
            public static DateSpan Subtract(DateTime x, DateTime y)
            {
                int ix = int.Parse(x.ToString("yyyyMMdd"));
                int iy = int.Parse(y.ToString("yyyyMMdd"));
                int diff = ix - iy;
                int sign = Math.Sign(diff);
                string s = Math.Abs(diff).ToString("D8");
                int years = int.Parse(s.Substring(0, 4));
                int months = int.Parse(s.Substring(4, 2));
                if (months >= 12)
                    months = 12 - 100 + months;
                int days = int.Parse(s.Substring(6, 2));
                int daysInMonth = DateTime.DaysInMonth(x.Year, x.Month);
                if (days >= daysInMonth)
                    days = daysInMonth - 100 + days;
                return new DateSpan(sign*years, sign*months, sign*days);
            }
     
            public override string ToString()
            {
                return string.Format("{0} year(s), {1} month(s) and {2} day(s)", _years, _months, _days);
            }
        }

    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    DateSpan diff = DateSpan.Subtract(datefin, datedebut);

    (j'ai pas testé de façon très approfondie, il faudrait faire des tests sur les cas limites...)

  8. #8
    Membre émérite

    Homme Profil pro
    Inscrit en
    Mars 2012
    Messages
    691
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Israël

    Informations forums :
    Inscription : Mars 2012
    Messages : 691
    Par défaut
    Bonjour

    un truc pas logique avec le nombre de mois entre deux date
    ex
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Dim datedebut As Date = New Date(1992, 1, 15)
        Dim datefin As Date = New Date(1992, 2, 1)
        totalmois = DateDiff(DateInterval.Month, datedebut, datefin)
    on obtient 1 mois or il y n' a que 17 jours entre les deux

    ou encore

    Dim datedebut As Date = New Date(1992, 12, 31)
    Dim datefin As Date = New Date(1993, 1, 1)

    totaljours = 1
    totalmois = 1
    totalannee = 1

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Calcul de durée entre deux dates en années, mois, jours, heures, minutes, secondes et reste
    Par Invité dans le forum Algorithmes et structures de données
    Réponses: 19
    Dernier message: 02/10/2015, 12h31
  2. [AC-2007] Reunir en un champs une date separé (année, mois ,jour)
    Par mbarrette3 dans le forum Requêtes et SQL.
    Réponses: 4
    Dernier message: 05/10/2011, 14h48
  3. date en année/mois/jour
    Par marcusien dans le forum Windows Forms
    Réponses: 6
    Dernier message: 13/03/2007, 14h58
  4. Réponses: 2
    Dernier message: 21/07/2006, 14h04

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