DATEADD (Transact-SQL)

Retourne une date spécifiée avec l'intervalle number indiqué (entier signé) ajouté à une datepart spécifiée de cette date.

Pour obtenir une vue d'ensemble de tous les types de données et fonctions de date et d'heure Transact-SQL, consultez Types de données et fonctions de date et d'heure (Transact-SQL). Pour obtenir des informations et des exemples communs aux types de données et fonctions de date et d'heure, consultez Utilisation des données de date et d'heure.

Icône Lien de rubriqueConventions de syntaxe de Transact-SQL

Syntaxe

DATEADD (datepart , number, date )

Arguments

  • datepart
    Partie de date à laquelle un integernumber est ajouté. Le tableau suivant répertorie tous les arguments datepart valides. Les équivalents de variables définis par l'utilisateur ne sont pas valides.

    datepart

    Abréviations

    year

    yy, yyyy

    quarter

    qq, q

    month

    mm, m

    dayofyear

    dy, y

    day

    dd, d

    week

    wk, ww

    weekday

    dw, w

    hour

    hh

    minute

    mi, n

    second

    ss, s

    millisecond

    ms

    microsecond

    mcs

    nanosecond

    ns

  • number
    Expression qui peut être résolue en une valeur int qui est ajoutée à une datepart de date. Les variables définies par l'utilisateur sont valides.

    Si vous spécifiez une valeur avec une fraction décimale, la fraction est tronquée et n'est pas arrondie.

  • date
    Est une expression qui peut être résolue en une valeur time, date, smalldatetime, datetime, datetime2 ou datetimeoffset. date peut être une expression, une expression de colonne, une variable définie par l'utilisateur ou un littéral de chaîne. Si l'expression est un littéral de chaîne, elle doit être résolue en datetime. Pour éviter toute ambiguïté, représentez les années à l'aide de quatre chiffres. Pour plus d'informations sur les années à deux chiffres, consultez Option two digit year cutoff.

Types des valeurs renvoyées

Le type de données retournées est le type de données de l'argument date, à l'exception des littéraux de chaîne.

Le type de données retournées pour un littéral de chaîne est datetime. Une erreur sera déclenchée si l'échelle des secondes du littéral de chaîne comprend plus de trois positions (.nnn) ou contient la partie du décalage de fuseau horaire.

[!REMARQUE]

Si les littéraux de chaîne ne sont pas convertis explicitement pour le paramètre date, les paramètres régionaux qui utilisent un format de date jour-mois-année (jma) peuvent obtenir des résultats incorrects lorsque DATEADD est utilisé conjointement à d'autres fonctions de date/heure.

Retour d'un type datetime2

DATEADD retourne un type datetime2 lorsque le paramètre date présente un type datetime2. Lorsque vous utilisez des littéraux de chaîne pour le paramètre date, vous devez les convertir explicitement en type datetime2 pour DATEADD pour retourner un type datetime2.

Valeur de retour

Argument datepart

dayofyear, day et weekday retournent la même valeur.

Chaque datepart et ses abréviations retournent la même valeur.

Si datepart est month, si le mois date comprend plus de jours que le mois retourné et que le jour date n'existe pas dans le mois retourné, le dernier jour du mois retourné est renvoyé. Par exemple, septembre compte 30 jours ; par conséquent, les deux instructions suivantes retournent 2006-09-30 00:00:00.000:

SELECT DATEADD(month, 1, '2006-08-30')

SELECT DATEADD(month, 1, '2006-08-31')

Argument number

L'argument number ne peut pas dépasser la plage des int. Dans les instructions suivantes, l'argument pour number dépasse la plage des int de 1. Le message d'erreur suivant est retourné : « Une erreur de dépassement arithmétique s'est produite lors de la conversion de l'expression en type de données int ».

SELECT DATEADD(year,2147483648, '2006-07-31');
SELECT DATEADD(year,-2147483649, '2006-07-31');

Argument date

L'argument date ne peut pas être incrémenté à une valeur située hors de la plage de son type de données. Dans les instructions suivantes, la valeur number qui est ajoutée à la valeur date dépasse la plage du type de données date. Le message d'erreur suivant est retourné : « L'ajout d'une valeur à une colonne datetime a provoqué un dépassement de capacité ».

SELECT DATEADD(year,2147483647, '2006-07-31');
SELECT DATEADD(year,-2147483647, '2006-07-31');

Valeurs retournées pour une date smalldatetime et une partie de date seconde ou fractions de seconde

La partie secondes d'une valeur smalldatetime est toujours 00. Si date est smalldatetime, les éléments suivants s'appliquent :

  • Si datepart est second et number se situe entre -30 et +29, aucun ajout n'est effectué.

  • Si datepart est second et number est inférieur à -30 ou supérieur à +29, l'ajout est effectué en commençant à une minute.

  • Si datepart est millisecond et number se situe entre -30001 et +29998, aucun ajout n'est effectué.

  • Si datepart est millisecond et number est inférieur à -30001 ou supérieur à +29998, l'ajout est effectué en commençant à une minute.

Notes

DATEADD peut être utilisé dans les clauses SELECT <list>, WHERE, HAVING, GROUP BY et ORDER BY.

Précision en fractions de seconde

L'ajout pour un datepart de microsecond ou nanosecond pour les types de données datesmalldatetime, date et datetime n'est pas autorisé.

Les millisecondes ont une échelle de 3 (,123). Les microsecondes ont une échelle de 6 (,123456). Les nanosecondes ont une échelle de 9 (,123456789). Les types de données time, datetime2 et datetimeoffset ont une échelle maximale de 7 (,1234567). Si datepart est nanosecond, number doit être égal à 100 avant que les fractions de seconde de date n'augmentent Un number situé entre 1 et 49 est arrondi à 0 et un nombre situé entre 50 et 99 est arrondi à 100.

Les instructions suivantes ajoutent un datepart de millisecond, microsecond ou nanosecond.

DECLARE @datetime2 datetime2 = '2007-01-01 13:10:10.1111111'
SELECT '1 millisecond' ,DATEADD(millisecond,1,@datetime2)
UNION ALL
SELECT '2 milliseconds', DATEADD(millisecond,2,@datetime2)
UNION ALL
SELECT '1 microsecond', DATEADD(microsecond,1,@datetime2)
UNION ALL
SELECT '2 microseconds', DATEADD(microsecond,2,@datetime2)
UNION ALL
SELECT '49 nanoseconds', DATEADD(nanosecond,49,@datetime2)
UNION ALL
SELECT '50 nanoseconds', DATEADD(nanosecond,50,@datetime2)
UNION ALL
SELECT '150 nanoseconds', DATEADD(nanosecond,150,@datetime2);
/*
Returns:
1 millisecond     2007-01-01 13:10:10.1121111
2 milliseconds    2007-01-01 13:10:10.1131111
1 microsecond     2007-01-01 13:10:10.1111121
2 microseconds    2007-01-01 13:10:10.1111131
49 nanoseconds    2007-01-01 13:10:10.1111111
50 nanoseconds    2007-01-01 13:10:10.1111112
150 nanoseconds   2007-01-01 13:10:10.1111113
*/

Décalage de fuseau horaire

L'ajout n'est pas autorisé pour le décalage de fuseau horaire.

Exemple

A. Incrémentation d'une partie de date d'un intervalle de 1

Chacune des instructions suivantes incrémente datepart d'un intervalle de 1.

DECLARE @datetime2 datetime2 = '2007-01-01 13:10:10.1111111'
SELECT 'year', DATEADD(year,1,@datetime2)
UNION ALL
SELECT 'quarter',DATEADD(quarter,1,@datetime2)
UNION ALL
SELECT 'month',DATEADD(month,1,@datetime2)
UNION ALL
SELECT 'dayofyear',DATEADD(dayofyear,1,@datetime2)
UNION ALL
SELECT 'day',DATEADD(day,1,@datetime2)
UNION ALL
SELECT 'week',DATEADD(week,1,@datetime2)
UNION ALL
SELECT 'weekday',DATEADD(weekday,1,@datetime2)
UNION ALL
SELECT 'hour',DATEADD(hour,1,@datetime2)
UNION ALL
SELECT 'minute',DATEADD(minute,1,@datetime2)
UNION ALL
SELECT 'second',DATEADD(second,1,@datetime2)
UNION ALL
SELECT 'millisecond',DATEADD(millisecond,1,@datetime2)
UNION ALL
SELECT 'microsecond',DATEADD(microsecond,1,@datetime2)
UNION ALL
SELECT 'nanosecond',DATEADD(nanosecond,1,@datetime2);
/*
Year         2008-01-01 13:10:10.1111111
quarter      2007-04-01 13:10:10.1111111
month        2007-02-01 13:10:10.1111111
dayofyear    2007-01-02 13:10:10.1111111
day          2007-01-02 13:10:10.1111111
week         2007-01-08 13:10:10.1111111
weekday      2007-01-02 13:10:10.1111111
hour         2007-01-01 14:10:10.1111111
minute       2007-01-01 13:11:10.1111111
second       2007-01-01 13:10:11.1111111
millisecond  2007-01-01 13:10:10.1121111
microsecond  2007-01-01 13:10:10.1111121
nanosecond   2007-01-01 13:10:10.1111111
*/

B. Incrémentation de plusieurs niveaux d'une partie de date dans une instruction

Chacune des instructions suivantes incrémente datepart d'un number assez grand pour incrémenter également le datepart immédiatement supérieur de date.

DECLARE @datetime2 datetime2;
SET @datetime2 = '2007-01-01 01:01:01.1111111';
--Statement                                 Result   
-------------------------------------------------------------------                                   
SELECT DATEADD(quarter,4,@datetime2);     --2008-01-01 01:01:01.110
SELECT DATEADD(month,13,@datetime2);      --2008-02-01 01:01:01.110
SELECT DATEADD(dayofyear,365,@datetime2); --2008-01-01 01:01:01.110
SELECT DATEADD(day,365,@datetime2);       --2008-01-01 01:01:01.110
SELECT DATEADD(week,5,@datetime2);        --2007-02-05 01:01:01.110
SELECT DATEADD(weekday,31,@datetime2);    --2007-02-01 01:01:01.110
SELECT DATEADD(hour,23,@datetime2);       --2007-01-02 00:01:01.110
SELECT DATEADD(minute,59,@datetime2);     --2007-01-01 02:00:01.110
SELECT DATEADD(second,59,@datetime2);     --2007-01-01 01:02:00.110
SELECT DATEADD(millisecond,1,@datetime2); --2007-01-01 01:01:01.110

C. Utilisation d'expressions comme arguments pour les paramètres de date et numériques

Les exemples suivants utilisent différents types d'expressions comme arguments pour les paramètres number et date.

Spécification de la colonne comme date

L'exemple suivant ajoute 2 jours à chaque OrderDate pour calculer une nouvelle PromisedShipDate.

USE AdventureWorks;
GO
SELECT SalesOrderID
    ,OrderDate 
    ,DATEADD(day,2,OrderDate) AS PromisedShipDate
FROM Sales.SalesOrderHeader;

Spécification de variables définies par l'utilisateur comme nombre et date

L'exemple suivant spécifie des variables définies par l'utilisateur comme arguments pour number et date.

DECLARE @days int;
DECLARE @datetime datetime;
SET @days = 365;
SET @datetime = '2000-01-01 01:01:01.111'; /* 2000 was a leap year */
SELECT DATEADD(day, @days, @datetime);

Spécification de la fonction système scalaire comme date

L'exemple suivant spécifie SYSDATETIME pour date.

SELECT DATEADD(month, 1, SYSDATETIME());

Spécification de sous-requêtes scalaires et de fonctions scalaires comme nombre et date

L'exemple suivant utilise des sous-requêtes scalaires et des fonctions scalaires, MAX(ModifiedDate), en tant qu'arguments pour number et date. (SELECT TOP 1 ContactID FROM Person.Contact) est un argument artificiel pour le paramètre numérique afin d'illustrer la sélection d'un argument number dans une liste de valeurs.

USE AdventureWorks;
GO
SELECT DATEADD(month,(SELECT TOP 1 ContactID FROM Person.Contact),
    (SELECT MAX(ModifiedDate) FROM Person.Contact));

Spécification de constantes comme nombre et date

L'exemple suivant utilise des constantes numériques et de caractère comme arguments pour number et date.

SELECT DATEADD(minute, 1, '2007-05-07 09:53:01.0376635');

Spécification d'expressions numériques et de fonctions système scalaires comme nombre et date

L'exemple suivant utilise des expressions numériques (-(10/2)), opérateurs unaires (-, un opérateur arithmétique (/) et des fonctions système scalaires (SYSDATETIME) comme arguments pour number et date.

SELECT DATEADD(month,-(10/2), SYSDATETIME());

Spécification de fonctions de classement comme nombre

L'exemple suivant utilise une fonction de classement comme arguments pour number.

USE AdventureWorks;
GO
SELECT c.FirstName, c.LastName
    ,DATEADD(day,ROW_NUMBER() OVER (ORDER BY
        a.PostalCode),SYSDATETIME()) AS 'Row Number'
FROM Sales.SalesPerson s 
    INNER JOIN Person.Contact c 
        ON s.SalesPersonID = c.ContactID
    INNER JOIN Person.Address a 
        ON a.AddressID = c.ContactID
WHERE TerritoryID IS NOT NULL 
    AND SalesYTD <> 0;

Spécification d'une fonction d'agrégation comme nombre

L'exemple suivant utilise une fonction d'agrégation comme argument pour number.

USE AdventureWorks;
GO
SELECT SalesOrderID, ProductID, OrderQty
    ,DATEADD(day,SUM(OrderQty) 
        OVER(PARTITION BY SalesOrderID),SYSDATETIME()) AS 'Total'
FROM Sales.SalesOrderDetail 
WHERE SalesOrderID IN(43659,43664);
GO

D. Utilisation de DATEADD pour les paramètres régionaux qui utilisent le format de date jma

Les exemples suivants indiquent comment utiliser des littéraux de chaîne avec DATEADD pour certains paramètres régionaux.

Montrer les pièges de l'utilisation d'une conversion implicite d'un littéral de chaîne

L'exemple suivant montre ce qui arrive lorsqu'un littéral de chaîne n'est pas converti explicitement.

SET LANGUAGE Español;

GO

SELECT DATENAME(m, DATEADD(d, 0,'1987-03-07'));

SELECT DATENAME(m, '1987-03-07');

GO

La première instruction select retourne julio (juillet) pour le mois, tandis que la deuxième retourne marzo (mars) pour le mois.

Solution pour éviter des résultats erronés en convertissant le littéral de chaîne explicitement

L'exemple suivant indique comment convertir explicitement le paramètre date pour éviter les résultats erronés.

SET LANGUAGE Español;

GO

SELECT DATENAME(m, DATEADD(d, 0, CAST('1987-03-07' AS datetime2)));

SELECT DATENAME(m, '1987-03-07');

GO

Les deux instructions select retournent marzo (mars) pour le mois.

Utilisation d'une variable datetime2 à la place d'un littéral de chaîne

L'exemple suivant évite l'utilisation directe d'un littéral de chaîne.

SET LANGUAGE Español;

GO

DECLARE @d datetime2 = '1987-03-07';

SELECT DATENAME(m, DATEADD(d, 0, @d));

SELECT DATENAME(m, @d);

GO

Voir aussi

Référence