【问题标题】:Proper way of getting rows since a date accounting for DST?自 DST 日期起获取行的正确方法?
【发布时间】:2020-11-05 11:40:51
【问题描述】:

我有一个日期时间列 changedate,我需要使用它来获取自下午 1 点以来在上周发生更改的行。不幸的是,本专栏采用的是当地时间 (EST)。服务器是 Microsoft SQL Server 2016。

这是我现在的查询:

DECLARE @since datetime = DATEADD(week,-1,SMALLDATETIMEFROMPARTS(YEAR(GETDATE()), MONTH(GETDATE()), DAY(GETDATE()), 13, 0)) AT TIME ZONE 'Eastern Standard Time'
SELECT * FROM table WHERE changedate AT TIME ZONE 'Eastern Standard Time' >= @since

由于我对列和@since 都使用了AT TIME ZONE,这是否能正确解释夏令时的变化?根据我找到的文档,这是我的理解,但我不能 100% 确定它是如何工作的,或者我是否遗漏了一些东西。

【问题讨论】:

    标签: sql sql-server timezone dst


    【解决方案1】:

    首先,确定您要比较的时间:

    -- Get the current date in the given time zone
    DECLARE @today date = convert(date, sysdatetimeoffset() AT TIME ZONE 'Eastern Standard Time')
    
    -- Get the date one week ago
    DECLARE @dateOneWeekAgo date = DATEADD(week, -1, @today)
    
    -- Join the date with the desired time (local to the same time zone)
    DECLARE @since datetime = convert(datetime, @dateOneWeekAgo) + convert(datetime, timefromparts(1, 0, 0, 0, 0))
    

    那就对比一下吧:

    SELECT * FROM table WHERE changedate >= @since
    

    假设您的changedate 字段是datetimedatetime2。如果是datetimeoffset,则应先将目标值转换为同一时区的datetimeoffset,然后改用:

    DECLARE @sinceDTO datetimeoffset = @since AT TIME ZONE 'Eastern Standard Time'
    

    关于你在问题中给出的方法,有两个问题:

    • getdate() 给出基于服务器本地时区的时间。东部时间可能不是同一天。

    • 你不应该对 where 子句中的表字段应用函数(无论是像 AT TIME ZONE 这样的内部函数还是其他函数),因为它会生成查询 non-sargable。换句话说,SQL 必须扫描整个表,而不是使用索引。表越大,查询速度越慢。

    【讨论】:

    • 哇,非常感谢,也感谢您的提示(显示我缺乏 SQL 知识)!因此,如果我理解正确,按照您的描述声明 @since 并将其用作 changedate 的标准(在 EDT 或 EST 中是 datetime)将正确解释该字段中的任何 DST 更改?
    • 假设该字段中的数据确实是在美国和加拿大观察到的东部时间 - 即冬季的 EST (UTC-5),夏季的 EDT (UTC-4) - 然后 是的。但是,如果由于某种原因,该字段中的数据实际上是 UTC-5,则将第一行更改为:DECLARE @today date = convert(date, switchoffset(sysdatetimeoffset(), '-05:00'))。见the switchoffset docs
    猜你喜欢
    • 2018-01-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-16
    • 2019-06-25
    • 1970-01-01
    • 1970-01-01
    • 2016-11-17
    相关资源
    最近更新 更多