Methodology
Méthodologie du calcul d’âge
Emprunt calendaire, pas de division naïve. L’erreur de 4 jours que le code naïf accumule.
By Buğra SözeriPublished
Calculer l’âge en années-mois-jours semble trivial. Ce ne l’est pas. L’approche naïve “aujourd’hui moins la date de naissance divisé par 365,25” dérive d’environ un jour tous les quatre à sept ans car les années réelles n’ont pas un nombre constant de jours. L’algorithme correct utilise l’emprunt calendaire — même logique que la soustraction à l’école primaire, mais avec des “chiffres” de longueur variable.
L’algorithme d’emprunt au mois
Étant donné une date de naissance (nY-nM-nJ) et aujourd’hui (aY-aM-aJ) :
- Différence d’années :
aY − nY. - Différence de mois :
aM − nM. Si négative, emprunter 1 à la différence d’années : soustraire 1 de la différence d’années, ajouter 12 à la différence de mois. - Différence de jours :
aJ − nJ. Si négative, emprunter 1 à la différence de mois : soustraire 1 de la différence de mois, ajouter la longueur du mois précédent à la différence de jours.
L’étape 3 est là où la plupart des implémentations échouent. La “longueur du mois précédent” n’est pas une constante 30 — elle vaut 28, 29, 30 ou 31 selon le mois et (pour février) l’année.
Exemple concret
Naissance : 1990-12-31. Aujourd’hui : 2026-03-15.
- Différence d’années : 2026 − 1990 = 36.
- Différence de mois : 3 − 12 = −9. Emprunt : la différence d’années passe à 35, la différence de mois devient 3.
- Différence de jours : 15 − 31 = −16. Emprunt : la différence de mois passe à 2, différence de jours += longueur du mois précédent. Le mois précédent est février 2026 (28 jours, pas bissextile). Différence de jours = −16 + 28 = 12.
Résultat : 35 ans, 2 mois, 12 jours.
L’astuce de la longueur du mois précédent
La façon la plus simple de demander “combien de jours avait le mois précédent ?” en JavaScript :
new Date(year, month, 0).getDate() // Retourne le dernier jour de (month - 1). // Le jour 0 du mois N est interprété comme le dernier jour de N-1.
Cela gère automatiquement la correction des années bissextiles de février car Date connaît la règle. new Date(2024, 2, 0).getDate() retourne 29 ; new Date(2023, 2, 0).getDate() retourne 28.
Anniversaires en année bissextile (29 fév.)
Les personnes nées le 29 février soulèvent une question récurrente : quel est leur anniversaire dans les années non bissextiles ? Deux conventions :
- Reporter au 1er mars — convention par défaut au Royaume-Uni et à Hong Kong.
- Reporter au 28 février — convention par défaut aux États-Unis, Taïwan, Nouvelle-Zélande. Le calculateur utilise celle-ci.
Le choix affecte le moment où “vous avez N ans” dans les années non bissextiles. Pour la plupart des usages cela n’a pas d’importance — la date de naissance sous-jacente est toujours le 29 fév. et la différence est d’un jour par année non bissextile.
Pourquoi “jours / 365,25” dérive
365,25 est la longueur moyenned’une année sur un cycle grégorien de 400 ans. Chaque année individuelle est 365 ou 366. Sur de courtes périodes la moyenne est une mauvaise approximation :
- 4 ans contiennent exactement 1 année bissextile → 1461 jours → 365,25 exact. Correct.
- La dérive provient de la règle du siècle : 1900 n’était pas une année bissextile (divisible par 100, pas par 400). 2000 l’était. Calculer des âges couvrant 1900 ou 2100 avec l’approximation 365,25 produit des erreurs visibles au niveau du jour.
Pour le calcul d’âge, l’emprunt calendaire est toujours exact. L’approximation naïve convient pour des estimations approximatives mais est incorrecte pour tout ce qui doit correspondre à un passeport ou un acte de naissance.
Détails de l’algorithme : emprunt au mois complet
L’implémentation de référence complète est suffisamment courte pour être reproduite ici ; la surprise est de voir combien peu de branches elle nécessite une fois que l’astuce du jour 0 gère le problème de longueur variable des mois.
function age(birth: Date, today: Date) {
let y = today.getFullYear() - birth.getFullYear();
let m = today.getMonth() - birth.getMonth();
let d = today.getDate() - birth.getDate();
if (d < 0) {
// Emprunter des jours du mois précédent — le jour 0 retourne le dernier jour du mois précédent.
const prevMonthLen = new Date(today.getFullYear(), today.getMonth(), 0).getDate();
d += prevMonthLen;
m -= 1;
}
if (m < 0) {
m += 12;
y -= 1;
}
return { years: y, months: m, days: d };
}L’algorithme s’exécute en temps O(1) sans division, sans arithmétique en virgule flottante et sans bibliothèques calendaires. La seule branche pilotée par la spécification est la gestion des années bissextiles — et même celle-ci est déléguée à Date, qui implémente la règle grégorienne (chaque année divisible par 4 sauf les années centenaires non divisibles par 400) issue de l’ECMA-262.
Comparaison avec l’approche naïve par comptage de jours sur une durée de 100 ans :
| Méthode | Résultat pour 1925-01-01 → 2025-01-01 | Erreur |
|---|---|---|
| Algorithme d’emprunt | 100 a, 0 m, 0 j | 0 j (exact) |
| (jours) / 365,25 | 99,9999 a → arrondi à 99 | ~1 j (erreur silencieuse) |
| (jours) / 365 | 100,07 a | ~25 j |
Sources & références
La règle des années bissextiles est la réforme grégorienne originale de 1582 (Inter Gravissimas) ; le format de date accepté est ISO 8601 ; l’astuce de la longueur du mois précédent est un comportement ECMAScript bien défini dans l’ECMA-262. Les conventions d’anniversaire du 29 fév. sont propres à chaque juridiction et découlent de législations nationales — voir notre guide des méthodes de calcul d’âgepour le tableau des juridictions. Le Royaume-Uni et Hong Kong reportent au 1er mars en vertu de la loi de 1953 sur l’état civil ; les États-Unis, la Nouvelle-Zélande et Taïwan utilisent le 28 fév. par convention administrative.
Hypothèses & limites
- Calendrier grégorien uniquement.Les calendriers Hijri, hébraïque, lunaire chinois et julien nécessitent des algorithmes différents ; le convertisseur n’expose pas la sélection du système calendaire.
- Date uniquement, pas date-heure.Les entrées sont tronquées à minuit dans le fuseau horaire local de l’utilisateur. Les changements d’heure DST n’affectent pas le résultat.
- Report du 29 fév. au 28 fév.Nous utilisons la convention américaine par défaut. Les utilisateurs des juridictions Royaume-Uni / Hong Kong doivent ajouter un jour au marqueur “vous avez N ans” dans les années non bissextiles.
- Aucun support avant l’adoption du calendrier grégorien. Les dates de naissance avant le 15 octobre 1582 utilisent l’extension grégorienne proleptique — historiquement celles-ci auraient été enregistrées comme des dates juliennes et décalées de 10 à 13 jours pour la comparaison moderne.
- Aucune gestion des secondes intercalaires.Les secondes intercalaires n’affectent pas l’arithmétique des jours calendaires ; si vous avez besoin de la précision UTC vs TAI, utilisez un autre outil.
- Les dates futures retournent zéro, pas un nombre négatif. Un âge négatif est presque toujours un bug d’interface utilisateur plutôt qu’un résultat légitime.
Cas limites gérés par le calculateur
- Dates de naissance futures — nous retournons zéro plutôt que des âges négatifs.
- Aujourd’hui égale la date de naissance — 0 ans, 0 mois, 0 jours.
- À travers les transitions DST— le calculateur utilise uniquement des mathématiques de dates (sans heures), donc les changements d’heure n’affectent pas le résultat.
Frequently asked questions
- Comment Convertitive calcule-t-il l’âge en années, mois et jours ?
- Nous utilisons un algorithme d’emprunt calendaire : calculer la différence brute en années, mois et jours, puis emprunter à l’unité supérieure quand un composant devient négatif. L’emprunt en jours utilise la longueur exacte du mois précédent (28, 29, 30 ou 31 jours), obtenue via JavaScript Date(année, mois, 0).getDate() pour que la correction des années bissextiles de février soit automatique.
- Pourquoi Convertitive n’utilise-t-il pas jours / 365,25 pour calculer l’âge ?
- 365,25 est la longueur moyenne d’une année sur le cycle grégorien de 400 ans, mais chaque année réelle dure exactement 365 ou 366 jours. L’utilisation de la moyenne produit une dérive d’environ 1 jour tous les quelques années et une erreur visible quand la plage de dates couvre une année centenaire comme 1900 (pas bissextile) ou 2100. L’algorithme d’emprunt est O(1), sans arithmétique en virgule flottante, et toujours exact.
- Que se passe-t-il avec les anniversaires du 29 février dans les années non bissextiles ?
- Convertitive reporte le 29 fév. au 28 fév. par défaut — la convention des États-Unis, Taïwan et Nouvelle-Zélande. La convention du Royaume-Uni et de Hong Kong reporte au 1er mars (conformément à la loi de 1953 sur l’état civil). Les deux conventions diffèrent d’un jour dans les années non bissextiles ; aucune convention n’est universellement correcte.
- Quel système calendaire le calculateur suppose-t-il ?
- Grégorien proleptique uniquement — la règle des années bissextiles issue de la réforme Inter Gravissimas de 1582 (divisible par 4, sauf les siècles, sauf les siècles divisibles par 400). Les entrées Hijri, hébraïques, chinoises lunaires et juliennes ne sont pas prises en charge. Les dates antérieures au 15 octobre 1582 utilisent l’extension grégorienne proleptique, qui diffère des dates juliennes enregistrées de 10 à 13 jours.
- Un changement d’heure DST affecte-t-il le résultat d’âge ?
- Non. Le calculateur opère sur des dates calendaires, pas des horodatages. Les entrées sont traitées comme minuit local sans composante horaire, donc aucun changement d’heure n’affecte le comptage des jours.
Related
Published May 15, 2026