SQL Server DateTimeOffset匹配相同的“日”

时间:2012-09-05 00:12:18

标签: sql tsql datetimeoffset

我的应用程序需要收集全球所有地点的“星期二”购买,其中“Tueday”是该地点的星期二(不论时区)。如果用户需要在下周重新运行报告,我还需要获得“上周二”的数据。我们所有的数据都是使用DateTimeOffset存储的。

所以 9/4/12 00:00:00 -7至9/4/12 23:59:59 -7 必须匹配 9/4/12 00:00:00 +11到9/4/12 23:59:59 +11 当我执行我的WHERE子句时。

我无法在WHERE子句中转换为UTC,因为这将获取伦敦“星期二”的数据(取决于DST),而不是位置的星期二。

我尝试从DateTimeOffset转换为DateTime,但似乎转换为UTC。 (在我的测试中,通过9/1/12至9/30/12获取了8/31/12数据。)

使用TSQL做这样的事情是否有诀窍?

谢谢!

2 个答案:

答案 0 :(得分:2)

恕我直言

DateTimeOffset = DateTime + Offset(来自UTC)

因此,您的数据已经代表客户的本地日期和时间。只需将其转换为DateTime,您将获得客户端的本地日期和时间。

但是如果您想将Offset添加到日期时间并希望得到Datetime那么

DECLARE @PurchaseDate DATETIMEOFFSET(7) = CAST('2007-05-08 12:30:29.1234567 +5:00' AS  datetimeoffset(7)) 

SELECT  CAST(SWITCHOFFSET (@PurchaseDate , '+00:00') AS DATETIME)

请查看此博客以获取更多信息。

http://blogs.msdn.com/b/bartd/archive/2009/03/31/the-death-of-datetime.aspx

答案 1 :(得分:1)

DATETIMEOFFSET转换为DATETIME时,它会将日期和时间视为值中的偏移量,并简单地删除时区。在转换为DATETIME时也是如此。因此,我认为您可以简单地将列转换为DATE,并将其与您希望匹配的仅限日期的值进行比较:

DECLARE @targetDate DATETIME2 = '2012-09-04' --Or we could use DATE here
SELECT [PurchaseId], [PurchaseTime], CAST([PurchaseTime] AS DATE) AS "PurchaseDate"
FROM [Purchases]
WHERE CAST([PurchaseTime] AS DATE) = @targetDate

我不确定这会有多高效(如果提供商真的很聪明,希望也不错 - 可能是哪个SQL Server),但你也可以通过限制原始列值来改进它:

DECLARE @targetDate DATETIME2 = '2012-09-04' --DATETIME2 so we can adjust by hours
SELECT [PurchaseId], [PurchaseTime], CAST([PurchaseTime] AS DATE) AS "PurchaseDate"
FROM [Purchases]
WHERE CAST([PurchaseTime] AS DATE) = @targetDate --Keep only the local-date matches
    AND [PurchaseTime] >= DATEADD(hh, -14, @targetDate) --Up to 14-hour time zone offset
    AND [PurchaseTime] <= DATEADD(hh, 38, @targetDate) --24 hours later plus 14

这应该有效地索引到一组可能性,然后在转换到本地日期时正确过滤。请注意,时区偏移最长可达14小时(新西兰距离我们最远的时间为+13:00,但根据MSDN可以到+/- 14:00),@ targetDate将在一天的开始,所以它比较早回到14小时和24 + 14 = 38小时后。 DATETIME2与DATETIMEOFFSET具有相同的范围和精度,因此它比原始的DATETIME更好(但它也可以用DATETIME工作)。