Date et heure DATEDIFF_AMJ4

Boostez vos compétences Excel avec notre communauté !

Rejoignez Excel Downloads, le rendez-vous des passionnés où l'entraide fait la force. Apprenez, échangez, progressez – et tout ça gratuitement ! 👉 Inscrivez-vous maintenant !

patricktoulon

XLDnaute Barbatruc
Bonjour a tous
j'avais fait une fonction "DATEDIFFAMJ" il y a quelque temps pour obtenir la différence entres deux date ans mois et jour
et un demandeur a faite une demande concernant la différence entre deux dates
sauf que lui avait besoins de faire la différence de dates 1 et 2 (entre deux siècles)
et pour couronner le tout avec des dates en dessous l'année 1900
j'ai donc repris ma fonction de base et utilisé une astuce simple
si pour la date la plus ancienne c'est une année divisible par 4 ou 400 je la décale en 2020( fevrier 28/29) sinon je la décale en 1904

10/10/2025
mise ajour de la fonction est est doté du multi ReturnMode
toujours la date2 en optional aussi histoire d'avoir l'anniversaire


en dessous 1800 non garantie

la fonction:

exemple d'utilisation en formule :

VB:
Function DATEDIFF_AMJ4$(ByVal dat1 As Date, Optional ByVal dat2 As Date = 0, Optional ReturnMode As String = 0)
    '**************************************
    ' fonction DateDiffAMJ V°4
    ' auteur:patricktoulon sur Exceldownloads
    ' date de mise en jour V°4:04/07/2021
    ' mise a jour supplementaire
    ' ajout de l'argument boolean "JustYear" pour ne récuprérer que les années
    ' mise à jour 09/102025
    ' suppression de l'argument boolean "Justyear" et remplaement par un variant
    ' pouvant ùodifier le return
    ' an ou mois ou jour ou les trois  en textuelou les trois en array
    '*************************************
    Dim A$, M$, J$, Ax&, Mx&, Jx, Dtemp$, et$, yeardécalée&, y
    If dat2 = 0 Then dat2 = Date
    If dat1 > dat2 Then Dtemp = dat2: dat2 = dat1: dat1 = Dtemp
    If Year(dat1) < 1904 Then If Year(dat1) Mod 4 <> 0 Or Year(dat1) Mod 400 <> 0 Then y = 2020 Else y = 1905
    If Year(dat1) < y Then
        'on decale la date la plus ancienne (Dat1)à l'année 1904
        yeardécalée = Abs((Year(dat1) - y))
        dat1 = DateSerial(Year(dat1) + yeardécalée, Month(dat1), Day(dat1))
        dat2 = DateSerial(Year(dat2) + yeardécalée, Month(dat2), Day(dat2))
    End If
    A = Evaluate("=DATEDIF(" & CLng(dat1) & "," & CLng(dat2) & ",""y"")"): Ax = A
    M = Evaluate("=DATEDIF(" & CLng(dat1) & "," & CLng(dat2) & ",""ym"")"): Mx = M
    J = Evaluate("=DATEDIF(" & CLng(dat1) & "," & CLng(dat2) & ",""md"")"): Jx = J
 
    A = IIf(A = 0, "", IIf(A = 1, A & " an ", A & " ans "))
    M = IIf(M = 0, "", IIf(M = 1, M & " mois", M & " mois"))
    J = IIf(J = 0, "", IIf(J = 1, "1 jour", J & " jours"))
    et = IIf(Val(A) > 0 Or Val(M) > 0, IIf(Val(J) > 0, " et ", " "), "")
       Select Case LCase(CStr(ReturnMode))
        Case "a", "1": DATEDIFF_AMJ4 = Ax
        Case "m", "2": DATEDIFF_AMJ4 = Mx
        Case "j", "3": DATEDIFF_AMJ4 = Jx
        Case "amj", "4", "0": DATEDIFF_AMJ4 = Application.Trim(A & M & " " & et & J)
        Case "T", 5: DATEDIFF_AMJ4 = Array(Ax, Mx, Jx)
    End Select
 End Function


Code:
=datediffAMJ4(date1;date2)      différence textuelle
=datediffAMJ4(date1)            anniversaire textuelle  par date2 par defaut
=datediffAMJ4(date1;date2;1)    année   argument (1 ou "a" ou "A")
=datediffAMJ4(date1;date2;2)    les mois   argument (2 ou "m" ou "M")
=datediffAMJ4(date1;date2,3)    les jours   argument (3 ou "j" ou "J")
=datediffAMJ4(date1;date2,4)    différence textuelle  argument (0 ou 4 ou "amj" ou "AMJ" )
=datediffAMJ4(date1;date2,5)    un array des trois datas de date argument (5 ou "t" ou "T") pratique pour le vba
petite démo
1760047154458.png


l'utilisation en VBA se fait de la même manière

et sauf erreur de ma part elle est compatible All version Excel
 
Dernière édition:
Bonjour a tous
j'avais fait une fonction "DATEDIFFAMJ" il y a quelque temps pour obtenir la différence entres deux date ans mois et jour
et un demandeur a faite une demande concernant la différence entre deux dates
sauf que lui avait besoins de faire la différence de dates 1 et 2 (entre deux siècles)
et pour couronner le tout avec des dates en dessous l'année 1900
j'ai donc repris ma fonction de base et utilisé une astuce simple
si pour la date la plus ancienne c'est une année divisible par 4 ou 400 je la décale en 2020( fevrier 28/29) sinon je la décale en 1904
j'ai ajouté un argument optional "JustYear" pour me donner uniquement la différence en année
j'ai mis date2 en optional aussi histoire d'avoir l'anniversaire
en dessous 1800 non garantie
la fonction:
VB:
Function DATEDIFF_AMJ4$(ByVal dat1 As Date, Optional ByVal dat2 As Date = 0, Optional JustYear As Boolean = False)
  '**************************************
'fonction DateDiffAMJ V°4
'auteur:patricktoulon sur Exceldownloads
'date de mise en jour V°4:04/07/2021
' mise a jour supplementaire
' ajout de l'argument boolean "JustYear" pour ne récuprérer que les années
'*************************************
  Dim A$, M$, J$, Dtemp$, et$, yeardécalée&, y
    If dat2 = 0 Then dat2 = Date
    If dat1 > dat2 Then Dtemp = dat2: dat2 = dat1: dat1 = Dtemp
    If Year(dat1) < 1904 Then If Year(dat1) Mod 4 <> 0 Or Year(dat1) Mod 400 <> 0 Then y = 2020 Else y = 1904
    If Year(dat1) < y Then
        'on decale la date la plus ancienne (Dat1)à l'année 1904
        yeardécalée = Abs((Year(dat1) - y))
        dat1 = DateSerial(Year(dat1) + yeardécalée, Month(dat1), Day(dat1))
        dat2 = DateSerial(Year(dat2) + yeardécalée, Month(dat2), Day(dat2))
    End If
    A = Evaluate("=DATEDIF(" & CLng(dat1) & "," & CLng(dat2) & ",""y"")")
    M = Evaluate("=DATEDIF(" & CLng(dat1) & "," & CLng(dat2) & ",""ym"")")
    J = Evaluate("=DATEDIF(" & CLng(dat1) & "," & CLng(dat2) & ",""md"")")
    A = IIf(A = 0, "", IIf(A = 1, A & " an", A & " ans"))
    M = IIf(M = 0, "", IIf(M = 1, M & " mois", M & " mois"))
    J = IIf(J = 0, "", IIf(J = 1, "1  jour", J & " jours"))
    et = IIf(Val(A) > 0 Or Val(M) > 0, IIf(Val(J) > 0, " et ", " "), "")
    DATEDIFF_AMJ4 = Application.Trim(A & IIf(Not JustYear, " " & M & " " & et & J, ""))
End Function

exemple d'utilisation en formule :

résultat complet souhaité
Code:
=datediff_amj4(A2;B2)

juste les années souhaitées
Code:
=datediff_amj4(A2;B2;1)

pour un anniversaire résultat complet (ans mois jour),on a besoins uniquement de la date 1
Code:
=datediff_amj4(A2)

pour un anniversaire juste les "ans",on a besoins uniquement de la date 1 et de l'argument "Justyear" (0 ou 1)
Code:
=datediff_amj4(A2;;1)
petite démo
Regarde la pièce jointe 1110159

l'utilisation en VBA se fait de la même manière

et sauf erreur de ma part elle est compatible All version Excel
Bonjour,

Déjà merci de ta fonction qui est superbe, tu sais quelle est l'année minimum possible pour la fonction ? 1800 ou moins ? Je suis curieux et je voudrais savoir.
 
bonjour @Etoto
normalement je vais même beaucoup plus bas
mais je cite @Victor21
Imposé par Grégoire XIII dans les États pontificaux, le calendrier grégorien fut aussi immédiatement adopté par l'Espagne, l'Italie, la Pologne et le Portugal.
En France, Henri III l'adopta le 9 décembre 1582, dont le lendemain fut le 20 décembre 1582
mais les différents parlements ont approuvé ce changement plus ou moins tardivement.
De plus, les provinces suivantes n'étaient pas françaises à l'époque :
Alsace : le 5 février 1682 est suivi par le 16 février 1682.
Lorraine : le 16 février 1760 est suivi par le 28 février 1760...

donc il serait inutile de descendre plus bas que 1761 surtout si on travaille des dates d’événement historique

cela dit si je teste
avec une date du genre 05/03/0365 avec "=DateDiff_AMJ4(A21) "j’obtiens bien 1656 ans et 4 mois

donc mathématiquement parlant la fonction est valide jusqu'en l'an 0100 mais pas plus bas
car vba interprète le nombre de l'année > que 9 de plus ou = à la dizaine de l'année en cours comme 20xx par contre si c'est >= alors 19xx
exemple
VB:
Sub test()
    MsgBox CDate("03/06/0020")
    MsgBox CDate("03/06/0022")
    MsgBox CDate("03/06/0029")
    MsgBox CDate("03/06/0030")
    MsgBox CDate("03/06/0036")
End Sub

donc je le redis mathématiquement parlant la fonction est valide jusqu'en l'an 0100
voila 😉
 
Re,
Imposé par Grégoire XIII dans les États pontificaux, le calendrier grégorien fut aussi immédiatement adopté par l'Espagne, l'Italie, la Pologne et le Portugal.
En France, Henri III l'adopta le 9 décembre 1582, dont le lendemain fut le 20 décembre 1582
mais les différents parlements ont approuvé ce changement plus ou moins tardivement.
De plus, les provinces suivantes n'étaient pas françaises à l'époque :
Alsace : le 5 février 1682 est suivi par le 16 février 1682.
Lorraine : le 16 février 1760 est suivi par le 28 février 1760...
Ok oui, c'est vrai que après les dates dessous 1761 peuvent êtres considérées comme erronées (même si je ne sais pas en quelle année le nouveau calendrier grégorien fut adopté en Suisse)
mathématiquement parlant la fonction est valide jusqu'en l'an 0100
Mais, l'an 100 c'est cool ça, merci de ta superbe fonction, je butais un peu avec les dates avant 1900 mais grâce à toi, j'ai déjà une superbe base.
 
re
je pourrais même ajouter - 11 jours si date en <= 9 décembre 1760 histoire d'aller plus loin
mais je sais pas si on devrait le considérer comme ça en fait car ça fait un mois de décembre à 19 jours
si @Victor21 passe par là il me diras 😉
 
[...]même si je ne sais pas en quelle année le nouveau calendrier grégorien fut adopté en Suisse[...]
@Etoto :
D'après mes sources -incomplètes :
Suisse1584du 12 du 21 novembreCantons de Lucerne, Uri, Schwitz, Zug et Fribourg
Suisse1724Cantons d'Unterwald et Appenzel, après avoir adopté une l" fois la réforme en 1584 et 1590 et être retournés au calendrier julien par la suite
Suisse1622Canton du Valais
Suisse1701du 1er au 11 janvierVilles (et cantons) de Zurich, Berne, Schaffhouse, Genève, Bienne, Neuchâtel, etc.
Suisse1724en janvierVilles (et cantons) de Saint
Suisse1784Canton des Grisons, pour partie, certaines régions ayant basculé en 1798, voire en 1811
 
@Etoto :
D'après mes sources -incomplètes :
Suisse1584du 12 du 21 novembreCantons de Lucerne, Uri, Schwitz, Zug et Fribourg
Suisse1724Cantons d'Unterwald et Appenzel, après avoir adopté une l" fois la réforme en 1584 et 1590 et être retournés au calendrier julien par la suite
Suisse1622Canton du Valais
Suisse1701du 1er au 11 janvierVilles (et cantons) de Zurich, Berne, Schaffhouse, Genève, Bienne, Neuchâtel, etc.
Suisse1724en janvierVilles (et cantons) de Saint
Suisse1784Canton des Grisons, pour partie, certaines régions ayant basculé en 1798, voire en 1811
Re,

Merci des infos @Victor21 👍 👍 .
 
Bonjour,

il y a une erreur dans le traitement qui induit des mauvais résultats.
"c'est une année divisible par 4 ou 400 je la décale en 2020"
Non. Déjà un nombre divisible par 400 sera toujours divisible par 4, ce test serait inutile en théorie.
Mais 1900 par exemple est divisible par 4 et n'est pas bissextile.

Il faut distinguer si tu as affaire à un siècle (divisible par 100) auquel cas c'est bissextile si divisible par 400.
Pour les autres années c'est bissextile si divisible par 4.
Si tu considères ta fonction valide pour les années >= 1584 tu peux simplifier en ajoutant 800 ans d'office aux date si dat1<=1901 (pour ôter le bug de 1900 bissextile pour excel)

Par ailleurs ta fonction annonce 3 jours (?) pour 28/02/1900 au 01/03/1900.
En vrai c'est 1, avec ton erreur ça devrait être 2 mais 3...
Je pense que c'est dû au fait que les n° de série diffèrent de 1 entre excel (bogué) et vba pour les dates inférieures au 01/03/1900.
Par exemple 1 c'est 01/01/1900 pour excel mais 31/12/1899 pour vba
Pour bien faire, il faudrait pour ces dates traiter différemment si la date vient d'une feuille ou de vba.
A voir si la correction corrigera aussi ce cas

1660429669874.png

eric
 
Bonjour @Dand87
je pense que tu n'a pas bien suivi le sujet
les formule datedif ne t'on jamais fait defaut?
ben voila ça commence aujourd'hui ,tu es dans les choux
1760041904981.png


avec ma fonction
1760042116532.png


d'autres part nous sommes dans une section de proposition de fonctions persos pas sur un forum
donc sauf proposition de correctif sur ma fonction ouvre ton propre topic avec ta proposition
en l’occurrence ici ta proposition est absolument inutile et ne fait que polluer ce topic
 
Bonjour @Dand87
je pense que tu n'a pas bien suivi le sujet
les formule datedif ne t'on jamais fait defaut?
ben voila ça commence aujourd'hui ,tu es dans les choux
Regarde la pièce jointe 1223393

avec ma fonction
Regarde la pièce jointe 1223394

d'autres part nous sommes dans une section de proposition de fonctions persos pas sur un forum
donc sauf proposition de correctif sur ma fonction ouvre ton propre topic avec ta proposition
en l’occurrence ici ta proposition est absolument inutile et ne fait que polluer ce topic
Oui, je viens de lire toute la discussion!

J'avais une formule pour le calcul depuis l'an 0! Je la cherche... ou la re-développe.
 
je descends jusqu’à 100
je pense que la palette est large, pas la peine de surenchérir
surtout que ma fonction est doté de la date Today par defaut en date2
je vois pas trop ce que l'on peut y apporter de plus
peut être un return sequenciel peut être histoire d'avoir les an mois jour séparément
j'e n'ai pas juger utile a l’époque mais ca peut être un plus
c'est pas grand chose à faire mais si tu veux t y coller fait toi plaisir
là au moins ce serait un plus
et du coup je l'ai fait la mise a jour
on voit bien que la ou les formules deraillent ma fonction elle tient la route

1760046081934.png

elle est maintenant dotée du multi mode de return
elle peut renvoyer
  • les années
  • les mois
  • les jours
  • l'anniversaire textuellement exprimée
  • et un array des 3 data de date
  • avec la date2 toujours en option
Code:
=datediffAMJ4(date1;date2)      différence textuelle
=datediffAMJ4(date1)                anniversaire textuelle  par date2 par defaut 
=datediffAMJ4(date1;date2;1)   année   argument (1 ou "a" ou "A")
=datediffAMJ4(date1;date2;2)    les mois   argument (2 ou "m" ou "M")
=datediffAMJ4(date1;date2,3)    les jours   argument (3 ou "j" ou "J")
=datediffAMJ4(date1;date2,5)    un array des trois datas de date argument (5 ou "t" ou "T") pratique pour le vba
avec ça Mr prendra un dessert
la mise a jour a été modifié dans le post 1
 
Bonjours Patrick et à tous

Tout d'abord bravo pour ta fonction super.
de mon coté j'ai voulu vérifier ta petite démonstration avec mon programme.
le résultat correspond point par point, la seule chose que je ne traite pas ce sont les date non européennes.
voici mon résultat.


Ce jour : 09 oct 2025
Naissance : vendredi 05 mai 1995
Âge : 30 ans 5 mois 4 jours
Nb Jours : 11115 Jours
Ce jour : 15 juin 1981
Naissance : mercredi 22 avril 1896
Âge : 85 ans 1 mois 24 jours
Nb Jours : 31099 Jours
Ce jour : 14 juin 2021
Naissance : samedi 21 février 1789
Âge : 232 ans 3 mois 24 jours
Nb Jours : 84849 Jours
Ce jour : 09 oct 2025
Naissance : vendredi 01 janvier 0100
Âge : 1925 ans 9 mois 8 jours
Nb Jours : 703373 Jours

Amicalement

Jean-Paul
 
- Navigue sans publicité
- Accède à Cléa, notre assistante IA experte Excel... et pas que...
- Profite de fonctionnalités exclusives
Ton soutien permet à Excel Downloads de rester 100% gratuit et de continuer à rassembler les passionnés d'Excel.
Je deviens Supporter XLD
Retour