【问题标题】:Why does SQL Server dateadd datediff behave behave this way when using weeks为什么 SQL Server dateadd datediff 在使用周时会有这种行为
【发布时间】:2015-08-03 18:29:13
【问题描述】:

当使用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

【问题讨论】:

    标签: sql sql-server date rounding


    【解决方案1】:

    问题是 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
    

    【讨论】:

    • 谢谢。我从来没有注意到 datediff 在一周的开始有固定的一天。 -1 技巧很酷。现在我只需要决定 3 个月后当我需要维护这段代码时,哪种实现更有意义:|
    【解决方案2】:

    这个日期四舍五入算法,翻译成英文,措辞如下:

    在日历的开头(第 0 天)添加一些 [时间单位]

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

    1900/01/01 是星期一。

    因此,您将整周数添加到星期一。因此,一周总是四舍五入到星期一。这会将 7/19 和 7/26(星期日)推到周末。

    【讨论】:

    • 不正确,如果您使用SET DATEFIRST {#} 更改一周的开始,它不会改变,而且 19 日是星期日,应该将其设置为前一个星期一(而不是后天)
    • 我不是在说一周的开始,我说的是第 0 天是星期一。 OP 从第 0 天开始获取周数,然后将其添加回第 0 天以获得周的开始。但是在第 0 天添加周意味着添加到星期一,因为第 0 天是星期一。无论 DATEDIFF 使用星期日还是星期一都无所谓,结果不会有所不同。 (当然我知道 DATEDIFF 必须使用 Sunday 并且不能更改)
    • 如果您想知道我在说什么,请尝试将“wk”的脚本行中的两个 0 替换为“1970-1-1”。您将在星期四开始数周!这就是 -1 技巧起作用的原因。这不是因为一周的开始。这是因为第 0 天。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-04-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多