为什么SQL Server dateadd datediff在使用周时表现得像这样

时间:2015-08-03 09:16:30

标签: sql sql-server date rounding

当使用dateadd/datdiff技巧来整理日期时,我总是有几天和几个月可预测且可理解的结果。我现在第一次使用它几个星期,我正在经历一些我没想到的事情 2015年7月19日和26日似乎进入了我认为的下周。以下示例说明了第二列中的实际行为以及第三列中的预期行为。我想了解为什么以及如何有所不同。

declare @n as table ([N] [int] )

insert into @n ( [N] ) values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),(12),(13),(14),(15)
select n
,      dateadd(dd,n,'2015-jul-17')
,      dateadd(wk,datediff(wk,0,  dateadd(dd,n,'2015-jul-17')  ),0)
,      dateadd(dd,datediff(dd,0,  dateadd(dd,n,'2015-jul-17')  )/7*7,0)
from @n
order by n

2 个答案:

答案 0 :(得分:3)

问题是DATEDIFF()一周使用星期日作为一周的开始日而不是星期一。

技巧是-1:

declare @n as table ([N] [int])
declare @start datetime = '1900-01-01'


insert into @n ( [N] ) values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),(12),(13),(14),(15)
select n
,                           dateadd(dd,n,@start) as [Date]
,dateadd(wk,datediff(wk,0,  dateadd(dd,n,@start) -1 ),0) as [WeekStart (by WeekDiff)]
,dateadd(dd,datediff(dd,0,  dateadd(dd,n,@start)    )/7*7,0) as [WeekStart (by DayDiff)]
,           datediff(wk,0,  dateadd(dd,n,@start)) [WeekDiff]
from @n
order by n

Is it possible to set start of week for T-SQL DATEDIFF function?

修改

DATEPART(WEEKDAY)SET DATEFIRST 1

一起使用
SET DATEFIRST 1

;with dates(value) as (select convert(date, dateadd(dd,n,@start)) from @n)
select *, DATEADD(Day, -DATEPART(WEEKDAY, value) + 1, value) from dates

答案 1 :(得分:0)

此日期舍入算法(翻译为英语)的措辞如下:

  

将多个[时间单位]添加到日历的开头(第0天)

其中[时间单位]是年/月/日/小时等......日历的开始时间是1900/01/01 00:00:00在T-SQL中。

1900/01/01是星期一。

所以你要在星期一加上整周的数量。因此本周总是四舍五入到周一。这将把7/19和7/26(星期日)抛到一周结束。