2014-07-10 3 views
1

Comment le calcul pour arriver MOIS datepart à DATEADD()DATEADD Calcul

Ajouter mois

SELECT '2012-01-29' AS [Date], CAST(DATEADD(MONTH, 1, '2012-01-31') AS DATE) AS NextDate 
UNION 
SELECT '2012-01-31' AS [Date], CAST(DATEADD(MONTH, 1, '2012-01-31') AS DATE) AS NextDate 
UNION 
SELECT '2013-01-31' AS [Date], CAST(DATEADD(MONTH, 1, '2013-01-31') AS DATE) AS NextDate 

Résultat

enter image description here

Subt Ract Mois

SELECT '2012-02-29' AS [Date], CAST(DATEADD(MONTH, -1, '2012-02-29') AS DATE) AS PrevDate 
UNION 
SELECT '2012-03-01' AS [Date], CAST(DATEADD(MONTH, -1, '2012-03-01') AS DATE) AS PrevDate 

Résultat

enter image description here

Lorsque j'ajoute un mois pour les dates 29,30,31 of Jan'2012, je reçois le même résultat que February 29. Pour la soustraction, pour la date 29 Feb'2012, il affiche 29 Jan'2012. Il n'y a aucun moyen d'obtenir les dates 30 & 31 of Jan'2012.

Je veux connaître une brève explication.

Répondre

3

Le comportement est explicitement indiqué dans la documentation pour DATEADD:

DATEADD (datepart , number , date) 

...

Si datepart est mois et la date mois a plus de jours que la mois de retour et le date jour n'existe pas dans le mois de retour, le dernier jour de la mois de retour est retourné. Par exemple, septembre a 30 jours; Par conséquent, les deux instructions suivantes renvoient 2006-09-30 00: 00: 00.000:

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

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

Quant à savoir pourquoi il a ce comportement, tout se résume au fait que les mois de longueur variable moyenne que vous devez appliquer une certaine forme de compromis lors de l'exécution des maths de date, et aucune réponse "correcte" n'existe. Pensez-vous que le 31 janvier est «le dernier jour de janvier» ou «30 jours après le 1er janvier»? Les deux sont des façons correctes de penser à la 31e. Mais si vous changez January en February, vous obtenez maintenant deux dates différentes - le 28 ou le 29 février pour «le dernier jour de février» ou le 2 ou le 3 mars pour «30 jours après le 1er février».

Mais les fonctions doivent retourner une seule valeur. Je ne dis pas que SQL Server applique l'une des interprétations ci-dessus. Ce qu'il fait, cependant, est de s'assurer que si vous ajoutez, disons, 1 mois à une date particulière, vous pouvez être sûr que la date qui en résulte tombe le mois suivant.

Questions connexes