
ADD_MONTHS Oracle : maîtriser l’ajout de mois sur les dates SQL
La fonction ADD_MONTHS est l’une des fonctions de manipulation de dates les plus utilisées dans Oracle SQL. Elle permet d’ajouter ou de soustraire un nombre de mois à une date donnée, avec une précision et une fiabilité adaptées aux besoins des applications métier. Que vous calculiez des échéances contractuelles, des dates de renouvellement ou des périodes de facturation, ADD_MONTHS Oracle est un outil incontournable pour tout développeur SQL.
Définition et utilisation de ADD_MONTHS
La fonction ADD_MONTHS retourne une date correspondant à la date d’entrée à laquelle on a ajouté un nombre entier de mois. Elle fait partie de la bibliothèque native des fonctions de date d’Oracle Database et est disponible depuis les premières versions du moteur.
Cas d’usage en entreprise
Dans le monde professionnel, ADD_MONTHS intervient fréquemment dans les scénarios suivants :
- Gestion des contrats : calculer automatiquement la date d’échéance d’un contrat signé pour une durée de N mois.
- Facturation récurrente : générer les dates de prochaine facturation pour des abonnements mensuels ou trimestriels.
- Ressources humaines : déterminer la date de fin de période d’essai d’un employé (généralement 3 ou 6 mois après la date d’embauche).
- Finance et reporting : construire des plages de dates pour comparer les performances d’un mois à l’autre ou d’une année sur l’autre.
- Gestion des garanties : calculer la date d’expiration d’une garantie produit.
Un avantage majeur de ADD_MONTHS par rapport à une addition arithmétique classique (comme date + 30) est qu’elle gère intelligemment les fins de mois. Si la date de départ est le dernier jour d’un mois, le résultat sera également le dernier jour du mois cible, quel que soit le nombre de jours dans ce mois.
Syntaxe de ADD_MONTHS
La syntaxe de la fonction ADD_MONTHS est volontairement simple et ne comporte que deux paramètres :
ADD_MONTHS(date, integer)
Détail des paramètres
| Paramètre | Type | Description |
|---|---|---|
date | DATE | La date de départ. Peut être une colonne de type DATE, la fonction SYSDATE, ou une valeur littérale convertie avec TO_DATE. |
integer | NUMBER | Le nombre de mois à ajouter. Une valeur négative permet de soustraire des mois. Les valeurs décimales sont tronquées à l’entier le plus proche. |
Valeur de retour : La fonction retourne une valeur de type DATE. Si le premier paramètre est de type TIMESTAMP, Oracle le convertit implicitement en DATE avant de procéder au calcul.
Exemples pratiques de ADD_MONTHS en Oracle SQL
Exemple 1 – Calcul de la date de fin de contrat
Contexte métier : Une entreprise de services souhaite afficher, pour chaque client, la date de début de son contrat ainsi que sa date d’échéance, sachant que tous les contrats sont signés pour une durée de 12 mois.
-- Calcul de la date d'échéance des contrats clients
-- La table CONTRATS contient les colonnes : CLIENT_ID, NOM_CLIENT, DATE_DEBUT
SELECT
client_id,
nom_client,
date_debut,
-- Ajout de 12 mois à la date de début pour obtenir la date de fin
ADD_MONTHS(date_debut, 12) AS date_fin_contrat
FROM
contrats
ORDER BY
date_debut;
Résultat attendu (exemple) :
| CLIENT_ID | NOM_CLIENT | DATE_DEBUT | DATE_FIN_CONTRAT |
|---|---|---|---|
| 1001 | Dupont SAS | 01/03/2024 | 01/03/2025 |
| 1002 | Martin & Co | 31/01/2024 | 31/01/2025 |
Notez que pour le client Martin & Co dont le contrat débute le 31 janvier (dernier jour du mois), la date de fin tombe bien le 31 janvier de l’année suivante, également dernier jour du mois.
Exemple 2 – Identifier les contrats arrivant à échéance dans les 3 prochains mois
Contexte métier : Le service commercial souhaite extraire la liste des contrats dont la date d’échéance se situe dans les trois prochains mois, afin de contacter les clients pour un renouvellement proactif.
-- Extraction des contrats expirant dans les 3 prochains mois
-- Utilisation de ADD_MONTHS avec SYSDATE pour la date courante
SELECT
c.client_id,
c.nom_client,
c.date_debut,
ADD_MONTHS(c.date_debut, c.duree_mois) AS date_echeance,
-- Calcul du nombre de jours restants avant l'échéance
ADD_MONTHS(c.date_debut, c.duree_mois) - SYSDATE AS jours_restants
FROM
contrats c
WHERE
-- Le contrat n'est pas encore expiré
ADD_MONTHS(c.date_debut, c.duree_mois) >= SYSDATE
-- Et il expire dans moins de 3 mois
AND ADD_MONTHS(c.date_debut, c.duree_mois) <= ADD_MONTHS(SYSDATE, 3)
ORDER BY
date_echeance ASC;
Cet exemple illustre comment combiner ADD_MONTHS avec SYSDATE dans une clause WHERE pour filtrer dynamiquement des enregistrements en fonction de la date du jour. Cette technique est couramment utilisée dans les tableaux de bord de suivi commercial.
Erreurs courantes avec ADD_MONTHS
Erreur : utiliser ADD_MONTHS sur un type TIMESTAMP avec fuseau horaire
Problème : Si vous appliquez ADD_MONTHS directement sur une colonne de type TIMESTAMP WITH TIME ZONE ou TIMESTAMP WITH LOCAL TIME ZONE, Oracle retourne une erreur ou un résultat de type DATE sans le fuseau horaire, ce qui peut entraîner des incohérences dans vos données.
-- ❌ Utilisation incorrecte sur un TIMESTAMP WITH TIME ZONE
SELECT ADD_MONTHS(SYSTIMESTAMP, 3) FROM dual;
-- Retourne un type DATE, le fuseau horaire est perdu
Solution : Convertissez explicitement votre TIMESTAMP en DATE avant d’utiliser ADD_MONTHS, ou recastez le résultat vers le type souhaité après l’appel.
-- ✅ Conversion explicite avant utilisation
SELECT ADD_MONTHS(CAST(SYSTIMESTAMP AS DATE), 3) FROM dual;
-- ✅ Ou recast du résultat en TIMESTAMP
SELECT CAST(ADD_MONTHS(SYSDATE, 3) AS TIMESTAMP WITH TIME ZONE) FROM dual;
Bonne pratique : En présence de colonnes temporelles complexes, précisez toujours explicitement le type de données attendu en entrée et en sortie pour éviter toute conversion implicite non désirée.
Résumé
| Point clé | Détail |
|---|---|
| Fonction | ADD_MONTHS(date, integer) |
| Type retourné | DATE |
| Valeur négative | Soustrait des mois à la date |
| Fin de mois | Gérée automatiquement (dernier jour → dernier jour) |
| Décimales | Tronquées à l’entier le plus proche |
| Compatible TIMESTAMP | Oui, mais conversion implicite en DATE |
| Disponibilité | Toutes versions Oracle Database |
2 bonnes pratiques Oracle
- Privilégiez
ADD_MONTHSà l’arithmétique directe sur les dates : Une expression commedate_debut + 90ajoute des jours, pas des mois. Or trois mois ne font pas toujours 90 jours. Utilisez systématiquementADD_MONTHSdès que vous manipulez des durées exprimées en mois pour garantir l’exactitude de vos calculs. - Indexez intelligemment vos colonnes de dates : Si vous utilisez
ADD_MONTHSsur une colonne dans une clauseWHERE, l’index sur cette colonne ne sera pas utilisé (fonction-based blocking). Créez un function-based index ou réécrivez votre filtre pour que la colonne soit isolée à gauche de la comparaison.
Aller plus loin
Pour approfondir votre maîtrise des fonctions de date en Oracle SQL, nous vous recommandons de consulter les articles suivants sur courssql.com :
- MONTHS_BETWEEN Oracle : apprenez à calculer le nombre de mois entre deux dates, le complément naturel de
ADD_MONTHS. - LAST_DAY Oracle : découvrez comment obtenir le dernier jour d’un mois donné et combinez-la avec
ADD_MONTHSpour des calculs de fin de mois précis. - TRUNC sur les dates Oracle : maîtrisez la troncature des dates pour arrondir vos résultats au mois, à l’année ou à n’importe quelle unité temporelle dans vos requêtes Oracle.
