在 where 子句日期范围过滤器中使用 datetimeoffset 日期

Using datetimeoffset dates in where clause date range filter

使用SQL Server 2016。这是在一份报告的SP中。当给定日期范围为 02/22/2017 时,报告包括 02/21/2017 的项目。日期作为 DateTimeOffset 存储在数据库中。

在此查询中,我正在尝试在 22 日 return,但我也将获得 21 日。

@start和@end代表用户输入的日期范围。 @storeddate 是用于过滤报告的数据库中的日期。我的计划是转换偏移日期,然后拉出 'date' 部分进行过滤,但它不起作用。

declare @start date = '2017-02-22';
declare @end date = '2017-02-22';
declare @storeddate datetimeoffset = '2017-02-22 00:00:19.0000000 +00:00';


;with dates as 
(
    select @storeddate as 'raw'
        , @storeddate AT TIME ZONE 'Pacific Standard Time' as offset
        , CONVERT(datetime, @storeddate) AT TIME ZONE 'Pacific Standard Time' as dt
        , CONVERT(datetime, @storeddate AT TIME ZONE 'Pacific Standard Time') as d
        , CAST(CONVERT(datetime, @storeddate) AT TIME ZONE 'Pacific Standard Time' as date) as 'casted' 
        , @start as 'start'
        , @end as 'end'

)

select * from dates
WHERE (
    CAST(CONVERT(datetime, @storeddate) AT TIME ZONE 'Pacific Standard Time' as date) >= @start 
    AND CAST(CONVERT(datetime, @storeddate) AT TIME ZONE 'Pacific Standard Time' as date) < DATEADD(day, 1, @end) )

编辑以添加注释:

这有点奇怪。这是仅在俄勒冈州使用的 Intranet Web 应用程序。 Web 开发人员使用了一些 javascript 日期选择器库,将他的所有日期更改为 UTC,但他不知道如何将它们改回来,所以他只是将它们作为 datetimeoffset 存储在数据库中。所以现在我必须更改所有报告以显示正确的日期。 'At Time Zone' 修复了报告中日期的显示,但它在日期范围过滤器的 where 子句中不起作用。

这与您所在的时区有关吗?您在没有偏移量的情况下输入 @storeddate,然后看起来您正在评估太平洋时间(-8:00,不是吗?)。这似乎会改变返回的数据。

编辑:尝试使用 dateadd 修改日期:

declare @start date = '2017-02-22';
declare @end date = '2017-02-22';
declare @storeddate table (rawdate datetimeoffset) 
insert into @storeddate
values( '2017-02-22 00:00:19.0000000 +00:00')
,('2017-02-21 00:00:19.0000000 +00:00')
,('2017-02-22 00:18:19.0000000 +00:00')
,('2017-02-23 00:18:19.0000000 +00:00')

;with dates as 
(
    select rawdate as 'raw'
        , cast(dateadd(hh,-8,rawdate) as date)  as offset
        , @start as 'start'
        , @end as 'end'
        from @storeddate
)

select * from dates
WHERE (
    offset >= @start 
and    offset < DATEADD(day, 1, @end))

我将 CONVERT 的右括号放在错误的位置,所以我将 @storeddate 转换为日期而不是 @storedate AT TIME ZONE。所以答案是这样的:

WHERE CAST(CONVERT(datetime, @storeddate AT TIME ZONE 'Pacific Standard Time') as date)

而不是

WHERE CAST(CONVERT(datetime, @storeddate) AT TIME ZONE 'Pacific Standard Time' as date)

等...