
MONTHS_BETWEEN Oracle : calculer le nombre de mois entre deux dates
La fonction MONTHS_BETWEEN est une fonction Oracle SQL incontournable pour calculer l’intervalle de temps en mois entre deux dates. Que vous travailliez sur des calculs d’ancienneté, des échéances contractuelles ou des analyses financières, MONTHS_BETWEEN vous offre une précision décimale que les simples soustractions de dates ne permettent pas d’atteindre nativement.
Définition et utilisation de MONTHS_BETWEEN
La fonction MONTHS_BETWEEN retourne le nombre de mois séparant deux valeurs de type DATE. Le résultat est un nombre décimal (NUMBER) pouvant être positif, négatif ou nul selon l’ordre des arguments.
Contrairement à une simple soustraction de dates (qui renvoie un nombre de jours), MONTHS_BETWEEN tient compte des mois calendaires et des années, ce qui en fait un outil bien plus adapté pour les calculs métier de type :
- Gestion des ressources humaines : calcul de l’ancienneté d’un employé, durée d’un contrat ou d’une période d’essai.
- Finance et comptabilité : calcul des intérêts courus sur une période, durée de remboursement d’un prêt.
- CRM et marketing : durée d’abonnement d’un client, délai depuis le dernier achat.
- Gestion de projets : suivi des jalons, durée d’une phase de projet.
Si les deux dates tombent sur le même jour du mois, Oracle renvoie un entier exact. Dans les autres cas, la fraction est calculée en divisant le nombre de jours résiduels par 31 (convention Oracle fixe).
Syntaxe de MONTHS_BETWEEN
La syntaxe de la fonction est simple et ne prend que deux paramètres :
MONTHS_BETWEEN(date1, date2)
Paramètres
| Paramètre | Type | Description |
|---|---|---|
date1 | DATE | La date de fin (ou date la plus récente en usage courant) |
date2 | DATE | La date de début (ou date la plus ancienne en usage courant) |
Valeur de retour : un NUMBER représentant le nombre de mois entre date1 et date2.
- Si
date1 > date2, le résultat est positif. - Si
date1 < date2, le résultat est négatif. - Si
date1 = date2, le résultat est 0.
Remarque Oracle : les deux arguments doivent être de type DATE. Si vous utilisez des TIMESTAMP, Oracle effectuera une conversion implicite, mais il est recommandé de caster explicitement avec CAST(... AS DATE) pour éviter tout comportement inattendu.
Exemples pratiques de MONTHS_BETWEEN
Exemple 1 – Calcul de l’ancienneté d’un employé (RH)
Dans cet exemple, on calcule le nombre de mois d’ancienneté de chaque employé à partir de la table EMPLOYEES du schéma HR d’Oracle.
-- Calcul de l'ancienneté en mois et en années arrondies
-- pour chaque employé encore en poste (sans date de fin)
SELECT
employee_id,
first_name || ' ' || last_name AS nom_complet,
hire_date AS date_embauche,
SYSDATE AS date_aujourd_hui,
ROUND(MONTHS_BETWEEN(SYSDATE, hire_date), 0) AS anciennete_mois,
TRUNC(MONTHS_BETWEEN(SYSDATE, hire_date) / 12) AS anciennete_annees
FROM
hr.employees
ORDER BY
anciennete_mois DESC;
Explication :
MONTHS_BETWEEN(SYSDATE, hire_date): calcule le nombre de mois entre la date d’embauche et aujourd’hui.ROUND(..., 0): arrondit à l’entier le plus proche pour afficher un nombre de mois entier.TRUNC(... / 12): divise par 12 et tronque pour obtenir le nombre d’années complètes.- Le tri décroissant affiche les employés les plus anciens en premier.
Exemple 2 – Identification des contrats expirés depuis plus de 6 mois (CRM)
Dans une base de données commerciale, on cherche à identifier les contrats clients dont la date d’expiration remonte à plus de 6 mois, afin de déclencher une campagne de renouvellement.
-- Sélection des contrats expirés depuis plus de 6 mois
-- La date_fin est dans le passé et l'écart dépasse 6 mois
SELECT
c.contrat_id,
c.client_nom,
c.date_debut,
c.date_fin,
ROUND(MONTHS_BETWEEN(SYSDATE, c.date_fin), 1) AS mois_depuis_expiration
FROM
contrats c
WHERE
c.date_fin < SYSDATE
AND MONTHS_BETWEEN(SYSDATE, c.date_fin) > 6
ORDER BY
mois_depuis_expiration DESC;
Explication :
- La condition
date_fin < SYSDATEfiltre uniquement les contrats déjà expirés. MONTHS_BETWEEN(SYSDATE, c.date_fin) > 6: restreint aux contrats expirés depuis plus de 6 mois.ROUND(..., 1): affiche le résultat avec une décimale pour plus de précision.- Ce type de requête est directement exploitable dans un outil de CRM ou un reporting commercial.
Erreurs courantes avec MONTHS_BETWEEN
Erreur : passer un VARCHAR2 au lieu d’un DATE
Une erreur fréquente consiste à passer directement une chaîne de caractères comme argument, sans conversion explicite :
-- ❌ Code incorrect : risque d'erreur ORA-01858 ou résultat inattendu
SELECT MONTHS_BETWEEN('2024-12-31', '2024-01-01') FROM dual;
-- ✅ Code correct : conversion explicite avec TO_DATE
SELECT MONTHS_BETWEEN(
TO_DATE('31/12/2024', 'DD/MM/YYYY'),
TO_DATE('01/01/2024', 'DD/MM/YYYY')
) AS nb_mois
FROM dual;
Explication : Oracle peut effectuer une conversion implicite d’une chaîne en date, mais ce comportement dépend du paramètre NLS_DATE_FORMAT de la session. Si le format de la chaîne ne correspond pas au format NLS actif, Oracle lèvera l’erreur ORA-01858: un caractère non numérique a été trouvé à la place d'un chiffre ou pire, produira un résultat silencieusement erroné. Toujours utiliser TO_DATE avec un masque de format explicite.
Résumé de la fonction MONTHS_BETWEEN
| Caractéristique | Détail |
|---|---|
| Nom de la fonction | MONTHS_BETWEEN(date1, date2) |
| Type de retour | NUMBER (décimal) |
| Résultat positif | date1 est postérieure à date2 |
| Résultat négatif | date1 est antérieure à date2 |
| Fraction de mois | Calculée sur la base de 31 jours par mois (convention Oracle) |
| Compatible avec | Oracle 9i et versions supérieures |
| Erreur fréquente | Passage d’une chaîne VARCHAR2 sans TO_DATE |
Bonnes pratiques Oracle
- Toujours convertir les chaînes en DATE avec
TO_DATEet un masque de format explicite pour éviter les dépendances au paramètreNLS_DATE_FORMATdu serveur ou de la session. - Combiner
MONTHS_BETWEENavecROUNDouTRUNCselon le besoin métier : utilisezROUNDpour des affichages arrondis, etTRUNCpour compter uniquement les mois complets écoulés (par exemple, pour des calculs d’ancienneté contractuels stricts).
Aller plus loin avec les fonctions de dates Oracle
La maîtrise de MONTHS_BETWEEN s’inscrit dans un ensemble plus large de fonctions de manipulation de dates disponibles dans Oracle SQL. Pour approfondir vos compétences, nous vous recommandons d’explorer les sujets suivants :
- La fonction ADD_MONTHS en Oracle SQL : apprenez à ajouter ou soustraire un nombre de mois à une date, idéal pour calculer des échéances et des dates d’expiration.
- La fonction TO_DATE en Oracle SQL : maîtrisez la conversion de chaînes de caractères en dates avec des masques de format précis pour fiabiliser vos requêtes.
- La fonction TRUNC sur les dates en Oracle SQL : découvrez comment tronquer une date à un niveau de précision donné (jour, mois, année) pour des regroupements et comparaisons fiables.
