Dateadd和datediff获得月份的最后一天

时间:2015-04-08 13:19:33

标签: sql sql-server

我不明白为什么这个查询会在每年2月份完成这个伎俩而不是31天的月份?除了二月,我每个月都会得到30天。有人可以向我解释一下吗?

SELECT  dateadd( mm, -240 + 22, DATEADD(mm, 1 + DATEDIFF(mm, 0, GETDATE()), -1)) AS n

我使用上面的代码因为我需要在22位置输入一个数字以获得不同的日期。我把它用作日历函数,每个月的最后日期。

3 个答案:

答案 0 :(得分:1)

最简单的变体是:

DATEADD(month,DATEDIFF(month,'20010101',GETDATE()),'20010131')

基本上说DATEDIFF(month,'20010101',GETDATE()) - 自2001年1月以来已经过了多少(整个)月?然后将整个月份添加到2001年1月31日。但是当添加月份时,DATEADD将截断日期部分,如果那个月没有这样的日子 - 那么31将向下舍入到30,29或28,酌情。

上面提到的两个日期是任意的 - 我们需要使用的是任何一个月,其中包含31天。


如果你需要改变你得到的月份(而不是当前月份),你应该可以通过在这里添加或减去值来调整这个值:

DATEADD(month,DATEDIFF(month,'20010101',GETDATE()) + N,'20010131')

N允许您调整哪个月感兴趣(相对于当月)


此代码:

DATEADD(mm, 1 + DATEDIFF(mm, 0, GETDATE()), -1)

在最初的问题中,另一种获得“当月最后一天” 1 的方法 - 并获得与上述相同的舍入行为。因此,如果您在4月(今天)运行该代码,则会在4月30日之前完成。如果您再将DATEADD()操作应用到该日期,就像在问题中那样,那么它就永远无法将自身恢复到第31个。

如果您在二月份使用原始问题代码,那么情况会更糟。因此,让这样的代码正常工作的一个关键方面是仅使用DATEADD 一次,以达到最终正确的月份,以及舍入行为实际上对您有利的地方

1 在我看来,不太可读。我不明白为什么人是缩短日期部分说明符的粉丝,也不理解为什么他们更喜欢使用魔法数字,例如1899年12月31日的最终-1。< / p>

答案 1 :(得分:0)

SELECT Current_Timestamp As today
     , DateAdd(mm, DateDiff(mm, 0, Current_Timestamp), 0) As first_of_current_month
     , DateAdd(mm, DateDiff(mm, 0, Current_Timestamp) + 1, 0) As first_of_next_month
     , DateAdd(dd, -1, DateAdd(mm, DateDiff(mm, 0, Current_Timestamp) + 1, 0)) As last_of_current_month
;

答案 2 :(得分:0)

我通常按以下方式进行。

首先,获取当月的第一天:

SELECT CAST(DATEADD(DAY, 1 - DAY(GETDATE()), GETDATE()) AS DATE)

然后,获取下个月的第一天,在之前获得的日期中添加一个月:

SELECT CAST(DATEADD(MONTH, 1, DATEADD(DAY, 1 - DAY(GETDATE()), GETDATE())) AS DATE)

最后,将当月的最后一天作为下个月第一天的前一天:

SELECT CAST(DATEADD(DAY, -1, DATEADD(MONTH, 1, DATEADD(DAY, 1 - DAY(GETDATE()), GETDATE()))) AS DATE)