Sql-Server

是否有更簡潔的方法將 UTC 日期時間僅轉換為本地日期?

  • October 22, 2012

我正在嘗試編寫一個查詢,該查詢僅根據 UTC 日期時間欄位的本地日期部分對記錄進行分組。

例如,如果我的表包含10/19/2012 2:00:00,那麼它應該被分組為10/18/2012,因為我的當地時間是 EST (-5h) 並且我只對欄位的日期部分感興趣。

我知道我DateAdd(day, DateDiff(day, 0, MyDate), 0)只能從日期時間欄位中獲取日期部分,並且可以DateAdd(minute, DateDiff(minute, GetUtcDate(), GetDate()), MyUtcDate)將 UTC 日期時間轉換為本地日期時間。

但是將兩者結合起來嚴重冒犯了我。

在 SQL Server 2005 中,有沒有比這更好的方法來獲取 UTC DateTime 欄位的 Date 部分,轉換為本地時間?

 SELECT DateAdd(day, DateDiff(day, 0, DateAdd(minute, DateDiff(minute, GetUtcDate(), GetDate()), MyUtcDate)), 0)
      , Count(*)
   FROM MyTable
GROUP BY DateAdd(day, DateDiff(day, 0, DateAdd(minute, DateDiff(minute, GetUtcDate(), GetDate()), MyUtcDate)), 0)

如果你不反對讓一個函式做臟活,這有助於使語句更清晰:

CREATE FUNCTION LocalDateFromUTCTime
(
   @UTCDateTime datetime
)
RETURNS datetime
BEGIN
   DECLARE @diff int;
   SET @diff = datediff(hh,GetUTCDate(), GetDate());
   RETURN DATEADD(day, DATEDIFF(day, 0, DATEADD(hh, @diff, @UTCDateTime)),0);
END

然後,您可以執行以下操作:

SELECT dbo.LocalDateFromUTCTime(MyUTCDate), COUNT(*)
FROM MyTable
GROUP BY dbo.LocalDateFromUTCTime(MyUTCDate);

當然,這確實使該語句成為非 SARGable。

如果由於您可能擁有大量記錄而主要關注可搜尋性,您可以在計算欄位上創建具有索引的物化視圖。


編輯:

根據@RichardThekiwi,此特定語句的 SARGability 不受使用該函式的影響,因為該函式既不是 aJOIN也不是WHERE子句的一部分。在使用該函式地方,它會在使用任何索引之後執行。

此外,上述程式碼不會截斷輸入到函式的日期的任何時間部分(這是設計使然)。因此,任何實施分鐘的時區,例如加拿大的愛德華王子島 (UTC -4:30)、印度 (UTC -4:30) 和加德滿都 (UTC +5:45)

引用自:https://dba.stackexchange.com/questions/27276