MONTHS_BETWEEN Oracle : calcul de mois entre deux dates

Découvrez la fonction MONTHS_BETWEEN d'Oracle SQL : syntaxe, exemples pratiques et erreurs courantes pour calculer des intervalles de mois entre deux dates.

Illustration du tutoriel SQL Oracle : MONTHS_BETWEEN Oracle : calcul de mois entre deux dates

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.

Publicité

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ètreTypeDescription
date1DATELa date de fin (ou date la plus récente en usage courant)
date2DATELa 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.

Publicité

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 < SYSDATE filtre 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éristiqueDétail
Nom de la fonctionMONTHS_BETWEEN(date1, date2)
Type de retourNUMBER (décimal)
Résultat positifdate1 est postérieure à date2
Résultat négatifdate1 est antérieure à date2
Fraction de moisCalculée sur la base de 31 jours par mois (convention Oracle)
Compatible avecOracle 9i et versions supérieures
Erreur fréquentePassage d’une chaîne VARCHAR2 sans TO_DATE

Bonnes pratiques Oracle

  1. Toujours convertir les chaînes en DATE avec TO_DATE et un masque de format explicite pour éviter les dépendances au paramètre NLS_DATE_FORMAT du serveur ou de la session.
  2. Combiner MONTHS_BETWEEN avec ROUND ou TRUNC selon le besoin métier : utilisez ROUND pour des affichages arrondis, et TRUNC pour 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 :

Publicité

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Publicité