8

我的应用程序需要收集全球所有地点的“星期二”购买,其中“星期二”是该地点的星期二(不考虑时区)。如果用户下周需要重新运行报告,我仍然需要获取“上周二”的数据。我们所有的数据都使用 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 做这样的事情有诀窍吗?

谢谢!

4

2 回答 2

2

恕我直言

DateTimeOffset = DateTime+Offset(来自 UTC)

因此,您的数据已经代表了客户的本地日期和时间。只需将其转换为 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

于 2012-09-05T00:51:45.993 回答
1

当转换 a 时DATETIMEOFFSETDATETIME它将日期和时间作为值中的偏移量,并简单地删除时区。DATE转换为or时也是如此TIME。因此,我认为您可以简单地将列转换为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 一起使用)。

于 2013-09-10T20:27:00.890 回答