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

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

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

    Informations forums :
    Inscription : Janvier 2013
    Messages : 836
    Points : 1 961
    Points
    1 961
    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 !
    Aider les autres, c'est encore la meilleure façon de s'aider soi-même. Martin Gray

    ToDo : Faire une ToDo List

  2. #2
    Expert confirmé
    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 : 41
    Localisation : Belgique

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

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 932
    Points : 4 242
    Points
    4 242
    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.
    Kropernic

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

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

    Informations forums :
    Inscription : Janvier 2013
    Messages : 836
    Points : 1 961
    Points
    1 961
    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.
    Aider les autres, c'est encore la meilleure façon de s'aider soi-même. Martin Gray

    ToDo : Faire une ToDo List

  4. #4
    Expert confirmé
    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 : 41
    Localisation : Belgique

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

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 932
    Points : 4 242
    Points
    4 242
    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.
    Kropernic

  5. #5
    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 : 42
    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
    Points : 39 749
    Points
    39 749
    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...)

  6. #6
    Membre éprouvé

    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
    Points : 929
    Points
    929
    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

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

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

    Informations forums :
    Inscription : Janvier 2013
    Messages : 836
    Points : 1 961
    Points
    1 961
    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
    Aider les autres, c'est encore la meilleure façon de s'aider soi-même. Martin Gray

    ToDo : Faire une ToDo List

  8. #8
    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 : 42
    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
    Points : 39 749
    Points
    39 749
    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

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

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

    Informations forums :
    Inscription : Janvier 2013
    Messages : 836
    Points : 1 961
    Points
    1 961
    Par défaut
    Il y a du beau travail quand même.

    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
    Je sais pas si c'est parce qu'on est lundi ou ... J'ai dû relire plusieurs fois pour tenter de comprendre.

    En gros c'est une histoire de retenue de la soustraction à rattraper pour poser sur une base 12, j'ai bon ?


    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
    Oui j'ai corrigé dans le version finale.
    Aider les autres, c'est encore la meilleure façon de s'aider soi-même. Martin Gray

    ToDo : Faire une ToDo List

  10. #10
    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 : 42
    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
    Points : 39 749
    Points
    39 749
    Par défaut
    Citation Envoyé par _Ez3kiel Voir le message
    Je sais pas si c'est parce qu'on est lundi ou ... J'ai dû relire plusieurs fois pour tenter de comprendre.
    D'autant plus que j'ai fait des fautes de frappe... il fallait bien sûr lire "99 mois" et non "99 fois"

    Citation Envoyé par _Ez3kiel Voir le message
    En gros c'est une histoire de retenue de la soustraction à rattraper pour poser sur une base 12, j'ai bon ?
    Oui c'est ça. Mais bon, j'ai fait ça un peu à l'intuition, sans chercher à vérifier si c'est mathématiquement correct...

    Citation Envoyé par _Ez3kiel Voir le message
    Oui j'ai corrigé dans le version finale.
    C'est à dire ? Tu as changé quoi ?

  11. #11
    Membre actif
    Profil pro
    Inscrit en
    Février 2006
    Messages
    505
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Février 2006
    Messages : 505
    Points : 293
    Points
    293
    Par défaut
    Je ne suis pas un expert en prog. mais ce que j'essayerais est de premièrement calculer le nombre d'année complet pour retirer le nombre de jours correspondant au nombre d'année trouvé, ensuite je vérifierais le nombre de mois complet pour ensuite enlever le nombre de jours entre ces deux mois, en théorie il devrais rester le nombre de jours.

    donc
    nbrAnnée entre 2006 et 2008 'si le mois 2008 est plus grand que 2006

    NbrMois entre Juillet et septembre 'si le jours de septembre est plus grand que juillet

    reste le nombre de jours

    je vous soumet mon idée comme ça

    bien à vous

  12. #12
    Membre actif
    Profil pro
    Inscrit en
    Février 2006
    Messages
    505
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Février 2006
    Messages : 505
    Points : 293
    Points
    293
    Par défaut
    vite fait comme ça

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     Dim Date1 As Date = "2010-01-01"
            Dim Date2 As Date = "2012-02-02"
            Dim NbrAn As Integer = DateDiff(DateInterval.Year, Date2, Date1)
            Console.WriteLine(NbrAn.ToString)
            Date2 = Date2.AddYears(NbrAn)
            Console.WriteLine(Date2.ToShortDateString)
    ensuite on calcule le nombre de mois etc.

  13. #13
    Membre éprouvé
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    667
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 667
    Points : 1 166
    Points
    1 166
    Par défaut
    Bonsoir,
    Mes tests me retournent des valeurs farfelues et négatives pour certaines dates genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
            Dim datedebut As Date = New Date(2008, 2, 1)
            Dim datefin As Date = New Date(2009, 1, 31)
    Ici une autre approche brute de décoffrage à affiner bien sur :
    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
            Dim datedebut As Date = New Date(2008, 2, 1)
            Dim datefin As Date = New Date(2009, 1, 31)
     
            Dim jrs As Integer = 0
            Dim annees As Integer = 0
            Dim mois As Integer = 0
            Dim dateTemp1 As Date
            Dim dateTemp2 As Date
     
            Dim result As Integer = DateTime.Compare(datedebut, datefin)
            If result < 0 Then
                dateTemp1 = datedebut
                dateTemp2 = datefin
            Else
                dateTemp1 = datefin
                dateTemp2 = datedebut
            End If
     
     
            jrs = Date.DaysInMonth(dateTemp1.Year, dateTemp1.Month) - dateTemp1.Day + dateTemp2.Day
            If jrs >= Date.DaysInMonth(dateTemp1.Year, dateTemp1.Month) Then
                jrs = jrs - Date.DaysInMonth(dateTemp1.Year, dateTemp1.Month)
                dateTemp1 = dateTemp1.AddMonths(-1)
                dateTemp2 = dateTemp2.AddDays(-dateTemp2.Day)
            Else
                dateTemp1 = dateTemp1.AddMonths(1)
            End If
     
            mois = CInt(DateDiff(DateInterval.Month, dateTemp1, dateTemp2))
            If mois >= 12 Then
                mois = mois Mod 12
            End If
     
            annees = CInt(DateDiff(DateInterval.Year, dateTemp1, dateTemp2))
            dateTemp1 = dateTemp1.AddYears(annees)
     
     
            MsgBox(annees & " ans " & mois & " mois " & jrs & " jours")

  14. #14
    Membre émérite Avatar de meziantou
    Homme Profil pro
    Ingénieur R&D
    Inscrit en
    Avril 2010
    Messages
    1 223
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : Canada

    Informations professionnelles :
    Activité : Ingénieur R&D
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2010
    Messages : 1 223
    Points : 2 439
    Points
    2 439
    Par défaut
    J'apporte ma petite touche:
    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
        Sub Main(args As String())
            DateDiff(New DateTime(2012, 1, 1), New DateTime(2013, 2, 2))   'La différence entre 01/01/2012 et 02/02/2013 est de 1 an, 1 mois, et 1 jour.
            DateDiff(New DateTime(2012, 12, 31), New DateTime(2013, 1, 1)) 'La différence entre 31/12/2012 et 01/01/2013 est de 0 an, 0 mois, et 1 jour.
            DateDiff(New DateTime(2012, 11, 30), New DateTime(2013, 1, 1)) 'La différence entre 30/11/2012 et 01/01/2013 est de 0 an, 1 mois, et 1 jour.
            DateDiff(New DateTime(1992, 1, 15), New DateTime(1992, 2, 1))  'La différence entre 15/01/1992 et 01/02/1992 est de 0 an, 0 mois, et 17 jour.
            DateDiff(New DateTime(1992, 1, 15), New DateTime(1992, 1, 15))  'La différence entre 15/01/1992 et 15/01/1992 est de 0 an, 0 mois, et 0 jour.
            DateDiff(New DateTime(1992, 1, 16), New DateTime(1992, 1, 15))  'La différence entre 15/01/1992 et 16/1/1992 est de 0 an, 0 mois, et 1 jour.
        End Sub
     
        Private Sub DateDiff(date1 As DateTime, date2 As DateTime)
            If (date1 > date2) Then
                DateDiff(date2, date1)
                Exit Sub
            End If
     
            Dim year As Integer = date2.Year - date1.Year
            Dim month As Integer = date2.Month - date1.Month
            Dim day As Integer = date2.Day - date1.Day
     
            If month < 0 Then
                year -= 1
                month += 12
            End If
     
            If day < 0 Then
                month -= 1
                day += DateTime.DaysInMonth(date1.Year, date1.Month)
            End If
     
            Console.WriteLine("La différence entre {0:d} et {1:d} est de {2} an, {3} mois, et {4} jour.", date1, date2, year, month, day)
        End Sub

  15. #15
    Inactif  

    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2012
    Messages
    4 904
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Finance

    Informations forums :
    Inscription : Janvier 2012
    Messages : 4 904
    Points : 10 168
    Points
    10 168
    Billets dans le blog
    36
    Par défaut
    Bonjour,

    J'ai pondu cela. Je ne l'ai pas testé à fond, mais cela semble aller.

    Cependant, Microsoft semble avoir programmé VB.net comme il a programmé Excel. Les calculs sur les dates semblent tenir compte des usages des financiers nord-américains; le premier jour de l'intervalle est le lendemain de la date de la transaction. Donc, si quelqu'un emprunte le 31 mars; le premier jour de l'intervalle est le premier avril. Donc, si on met date du début le 1 janvier 2013 et la date de fin le 31 décembre 2012; on obtient : 0 année(s),11 mois ,30 jours. Je te laisse le soin de décider ce que tu veux faire avec cela et d'augmenter de un, ou non, le nombre de jours.

    Je mets là la copie intégrale du module de code d'une Form avec un bouton pour lancer l'exécution et un textbox pour afficher les résultats. Rien de plus

    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
    Imports System.DateTime
     
    Public Class Form1
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            Dim datedebut As Date = New DateTime(1992, 1, 28)
            Dim datefin As Date = New DateTime(2009, 9, 1)
            premieressai(datedebut, datefin)
        End Sub
        Sub premieressai(datedebut As DateTime, datefin As DateTime)
            Dim lesannées As Integer = datefin.Year - datedebut.Year
            Dim lesmois As Integer = datefin.Month - datedebut.Month
            Dim lesjours As Integer = datefin.Day - datedebut.Day
            Dim lederniermois As Integer = datefin.Month
            Dim lederniermoiscomplet As Integer = 0
            Dim joursrestants As Integer = 0
            Dim dateréférence As DateTime = Nothing
     
            Select Case lesjours
                'Si le nombre de jours est négatif, c'est que l'on
                'a un mois de trop
                Case Is < 0
                    lesmois -= 1
                    lederniermoiscomplet = datefin.Month - 1
                    dateréférence = New Date(datefin.Year, lederniermoiscomplet, datedebut.Day)
                    lesjours = datefin.Subtract(dateréférence).TotalDays
            End Select
            Dim lerésultat As String = lesannées.ToString & " année(s)," & lesmois.ToString & " mois ," & lesjours.ToString & " jours"
            TextBox1.text = lerésultat
        End Sub
    End Class
    À ma connaissance, le seul personnage qui a été diagnostiqué comme étant allergique au mot effort. c'est Gaston Lagaffe.

    Ô Saint Excel, Grand Dieu de l'Inutile.

    Excel n'a jamais été, n'est pas et ne sera jamais un SGBD, c'est pour cela que Excel s'appelle Excel et ne s'appelle pas Access junior.

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

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

    Informations forums :
    Inscription : Janvier 2013
    Messages : 836
    Points : 1 961
    Points
    1 961
    Par défaut
    Wow, y'a eu du remue-méninges ici !

    @Mario Rousson: Oui mais comme tu dis "Si le mois n'est pas inférieur", or ce cas-là ne doit pas passer à la trappe pour moi.

    @chrismonoye: J'ai eu aussi des résultats faux, parfois, tu ne m'en voudras pas si je ne prend pas la temps de débugger ?

    @clementmarcotte: Je crois que tu ne gères pas le cas où le mois de début est supérieur au mois de fin, une fois ce cas traité ton code sera probablement correct, et sera relativement similaire à la logique de meziantou.

    @meziantou: Si on retire la notion d'Exit Sub (que je ne cautionne pas si l'on peut éviter .. ), l'algo est propre, facilement compréhensible, et traite bien tous les cas, je valide !

    @Tomlev: J'avais vu la faute de frappe mais ça restait compréhensible, mais du coup ça me laisse assez perplexe d'utiliser ce "bidouillage" mathématique...

    Citation Envoyé par Tomlev
    C'est à dire ? Tu as changé quoi ?
    Tu gérais le signe (je crois) dans le cas où les paramètres x(dateDebut) et y(DateFin) étaient inversés, mais ensuite tu faisais daysInMonth = DateTime.DaysInMonth(x.Year, x.Month) qui induit que X est forcément la date de début. (Si c'est bien ce dont tu parles)



    Encore merci à tous, ça fait plaisir à voir autant de gens qui se creusent la tête.
    Aider les autres, c'est encore la meilleure façon de s'aider soi-même. Martin Gray

    ToDo : Faire une ToDo List

  17. #17
    Membre actif
    Profil pro
    Inscrit en
    Février 2006
    Messages
    505
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Février 2006
    Messages : 505
    Points : 293
    Points
    293
    Par défaut
    Grrrr!!!

    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
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            Dim DateDep As Date = "2010-01-01"
            Dim Datefin As Date = "2012-02-02"
            Dim NbrAn As Integer = DateDiff(DateInterval.Year, Datefin, DateDep)
            Console.WriteLine(NbrAn.ToString)
            Dim DateTrans1 As Date = Datefin.AddYears(NbrAn)
            Console.WriteLine(DateTrans1.ToShortDateString)
     
            Dim NbrMois As Integer = DateDiff(DateInterval.Month, DateTrans1, DateDep)
            Console.WriteLine(NbrMois)
            DateTrans1 = DateTrans1.AddMonths(NbrMois)
            Dim NbrJours = DateDiff(DateInterval.Day, DateTrans1, DateDep)
            Console.WriteLine(Math.Abs(NbrAn).ToString)
            Console.WriteLine(Math.Abs(NbrMois).ToString)
            Console.WriteLine(Math.Abs(NbrJours).ToString)
        End Sub

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

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

    Informations forums :
    Inscription : Janvier 2013
    Messages : 836
    Points : 1 961
    Points
    1 961
    Par défaut
    Il y a toujours des soucis Mario Rousson
    Essaye avec ces 2 dates

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
            Dim DateDep As Date = Date.Parse("2010-09-28")
            Dim Datefin As Date = Date.Parse("2012-02-02")
            Dim NbrAn As Integer = CInt(DateDiff(DateInterval.Year, Datefin, DateDep))
            Dim DateTrans1 As Date = Datefin.AddYears(NbrAn)
            Dim NbrMois As Integer = CInt(DateDiff(DateInterval.Month, DateTrans1, DateDep))
     
     
            DateTrans1 = DateTrans1.AddMonths(NbrMois)
            Dim NbrJours = DateDiff(DateInterval.Day, DateTrans1, DateDep)
            Console.WriteLine(Math.Abs(NbrAn).ToString)
            Console.WriteLine(Math.Abs(NbrMois).ToString)
            Console.WriteLine(Math.Abs(NbrJours).ToString)
    Il retourne 2 ans, 7 mois et 26 jours.
    Or il n'y a que 1 an, 4 mois et 5 jours.

    Mais je te remercie pour la volonté d'aider ! Tu peux poursuivre en tant que défi personnel, mais je ne veux pas être tenu pour responsable de tes migraines.

    Je reste attaché à l'algo de meziantou qui est -à mes yeux- le plus propre et simple. (Tellement simple que je me mettrais des claques quand je vois à quel point je me suis pris la tête!)

    Merci encore une fois !
    Aider les autres, c'est encore la meilleure façon de s'aider soi-même. Martin Gray

    ToDo : Faire une ToDo List

  19. #19
    Membre émérite Avatar de meziantou
    Homme Profil pro
    Ingénieur R&D
    Inscrit en
    Avril 2010
    Messages
    1 223
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : Canada

    Informations professionnelles :
    Activité : Ingénieur R&D
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2010
    Messages : 1 223
    Points : 2 439
    Points
    2 439
    Par défaut
    Citation Envoyé par _Ez3kiel Voir le message
    Je reste attaché à l'algo de meziantou qui est -à mes yeux- le plus propre et simple. (Tellement simple que je me mettrais des claques quand je vois à quel point je me suis pris la tête!)
    Je ne veux pas être tenu responsable de violences sur développeur

  20. #20
    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 : 42
    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
    Points : 39 749
    Points
    39 749
    Par défaut
    Citation Envoyé par _Ez3kiel Voir le message
    Je reste attaché à l'algo de meziantou qui est -à mes yeux- le plus propre et simple. (Tellement simple que je me mettrais des claques quand je vois à quel point je me suis pris la tête!)
    J'avoue, c'est nettement plus compréhensible que mon truc...

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

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