将DateTimeOffset转换为DateTime并将结果与​​DateTime进行比较

时间:2013-07-23 03:23:07

标签: tsql datetime datetimeoffset

有时将DateTimeOffset转换为Datetime似乎会将DateTimeOffset字段恢复为UTC

我想查找特定日期之间发生的所有订单。 OrderDateTime存储为DateTimeOffset。

DECLARE @StartDate DATETIME = '20130723'
       ,@EndDate   DATETIME = '20130724'

SELECT cn.orderdatetime,
       LocalTime = CAST(orderdatetime AS datetime),
       facilityid
FROM ConsignmentNote cn
WHERE CAST(OrderDateTime AS DATETIME) BETWEEN @StartDate AND @EndDate

此查询的结果是(正如您所料)

OrderDateTime                         LocalTime                  Facilityid
2013-07-23 08:26:02.9120644 +10:00    2013-07-23 08:26:02.913    84
2013-07-23 08:27:43.9571506 +10:00    2013-07-23 08:27:43.957    84
2013-07-23 10:24:54.2930893 +10:00    2013-07-23 10:24:54.293    84

但我还需要在facilityID上过滤此结果集 - 但是如果我将facilityId添加到查询中:

DECLARE @StartDate DATETIME = '20130723'
       ,@EndDate   DATETIME = '20130724'

SELECT cn.orderdatetime,
       LocalTime = CAST(orderdatetime AS datetime),
       facilityid
FROM ConsignmentNote cn
WHERE CAST(OrderDateTime AS DATETIME) BETWEEN @StartDate AND @EndDate
AND FacilityId = 84

我得到以下结果

orderdatetime                       LocalTime               facilityid
2013-07-23 10:24:54.2930893 +10:00  2013-07-23 10:24:54.293 84

是什么给出的?为什么在查询螺丝上添加另一个参数日期? (nb facilityID 在consignmentNote表中是 int)

只是为了证明这一点 - 如果我将StartDate移回'20130722'一天,我得到了我想要的3行结果,这似乎表明:

 CAST (OrderDateTime as DateTime) 

是(有时?)处理不同,取决于它在SELECT或WHERE子句中,还是有其他参数? (好吧,它似乎不是一个统一的治疗方法)

任何人都可以指向我任何方向来解决这个问题吗?可能是Service Pack还是修补程序

Microsoft SQL Server 2008 R2(SP1) - 10.50.2500.0(X64)     2011年6月17日00:54:03     版权所有(c)Microsoft Corporation     Windows NT 6.1(Build 7601:Service Pack 1)上的企业版(64位)

btw - 我知道如果我创建一个只包含这些值的表 - 它只是按照您的预期(下面的代码)工作而没有任何问题 - 所以它必须是环境 - 是的?是的?

CREATE TABLE #temp (orderdatetime DATETIMEOFFSET,facilityid int)
INSERT INTO #temp VALUES ('2013-07-23 08:26:02.9120644 +10:00',84)
INSERT INTO #temp VALUES ('2013-07-23 08:27:43.9571506 +10:00',84)
INSERT INTO #temp VALUES ('2013-07-23 10:24:54.2930893 +10:00',84)

SELECT     orderdatetime,CAST(orderdatetime AS datetime),facilityid
FROM #temp 
WHERE    CAST(OrderDateTime AS DATETIME) BETWEEN @StartDate AND @EndDate
AND facilityid =84

DROP TABLE #temp

2 个答案:

答案 0 :(得分:1)

This guy试图与你偶然发现的情况相反。也就是说,他试图将他的datetimeoffsets转换为UTC。但是对于这种类型的铸造有一些讨论,我认为你会发现相关的。

在测试以下内容时:

DECLARE @Something datetimeoffset(7)

SET @Something = '2008-12-19 17:30:09.1234567 +11:00'

SELECT 1
WHERE DATEPART(hour, convert(datetime, @Something)) = 17

select cast(@Something as datetime)
select convert(datetime, @Something, 109)

似乎CONVERT不会在WHERE子句中将时区更改为UTC,也不会更改SELECT子句中的时区。但是,使用转换中的任何样式都将更改为UTC。

希望这有帮助。

答案 1 :(得分:1)

您对该列有索引吗?如果是这样,我认为您正在看到KB2715289中描述的问题的另一种变体。

根据那篇文章,问题已解决:

我建议您手动或通过Microsoft Update应用最新更新,看看是否还有问题。