为什么 SQL Server dateadd datediff 在使用周时会这样
Why does SQL Server dateadd datediff behave behave this way when using weeks
当使用 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
这个日期舍入算法,翻译成英文,可以表述如下:
Add a number of [Time Unit] to the start of calendar (Day 0)
其中 [Time Unit] 是 Year/Month/Days/Hours 等..... 日历开始时间是 1900/01/01 00:00:00 in T-SQL.
1900/01/01 是星期一。
因此您要将整周数加到星期一。因此,一周总是四舍五入到星期一。这会将 7/19 和 7/26(星期日)抛出到本周末。
问题是 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
当使用 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
这个日期舍入算法,翻译成英文,可以表述如下:
Add a number of [Time Unit] to the start of calendar (Day 0)
其中 [Time Unit] 是 Year/Month/Days/Hours 等..... 日历开始时间是 1900/01/01 00:00:00 in T-SQL.
1900/01/01 是星期一。
因此您要将整周数加到星期一。因此,一周总是四舍五入到星期一。这会将 7/19 和 7/26(星期日)抛出到本周末。
问题是 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