2015-07-10 43 views
1

無論什麼愚蠢的原因,我在處理時區時都很困惑。從SQL查詢轉換爲基於TimeZoneInfo的本地時間的datetimeoffset

當創建一個記錄,我用:

getutcdate() 

因此,例如,它是存儲在一個DATETIMEOFFSET列,看起來像這樣:

2015-07-03 20:44:21.0300000 +00:00 

所以沒有偏移,只是原始UTC。

現在,在服務器代碼中,我想要做一些事情......我有一個查詢讓我只是爲特定用戶發佈的文章的CreatedDate。我在一個數據表存儲這樣的:

Dim tz as TimeZoneInfo = GetUserTZInfo(User) 
Dim dt as DataTable = GetArticleDates(User) 
Dim MaxArticles As Integer = 5 
Dim PostedThisMonth As Integer 
Dim Remaining As Integer 

我有限的用戶元/月發表5篇文章,所以你可以看到,時間可以得到朝月的基礎上,開始或結束搖搖欲墜用戶的時區。這是明天的某個地方,然而到處都是同一時刻。

但我希望它是用戶友好的,只是基於用戶,而不是服務器時間。

我在上轉換爲本地時間,因爲我DATETIMEOFFSET的數據類型的使用一些例子困難

任何人都可以提出關於如何實現以下最佳實踐/方法:

  1. 搜索dt以查看與用戶的月份相等的任何創建日期。
  2. 根據找到的內容爲GeneratedMonth生成計數。

像我說的唯一的粘性區域是在月初或月底...基本上是12小時的窗口,當然是DST,但我不那麼在意。

非常感謝幫助!

+0

只需使用日期數學,並根據用戶時區進行調整。你有用戶的時區嗎? –

+0

@SeanLange我做的。我向你展示的示例函數爲用戶返回一個TimeZoneInfo對象。 – user1447679

+0

在數據庫中這樣做會更有意義嗎?否則,你必須返回所有的信息,然後過濾它。只會首先返回你想要的數據會更有效率。 –

回答

2

恭喜你,你領先於大多數人。通過在數據庫中存儲UTC時間並使用TimeZoneInfo跟蹤用戶的時區,您就可以做到這一點。

如果你從來沒有從+00偏離:00,你店JUSE一個datetimedatetime2代替datetimeoffset,但它不會傷害任何東西,所以它具有明確UTC的好處。

你真正需要做的是:

  • 使用用戶的時區,以用戶的本地每月的開始和結束轉換爲等效的UTC時間點發生。

  • 使用該值範圍查詢您的數據庫。

    // compute the start of this month and the next month, by the user's time zone 
    Dim today As DateTime = TimeZoneInfo.ConvertTime(DateTime.UtcNow, tz).Date 
    Dim startDateOfThisMonth As DateTime = New DateTime(today.Year, today.Month, 1) 
    Dim startDateOfNextMonth As DateTime = startDateOfThisMonth.AddMonths(1) 
    
    // convert those to UTC 
    Dim startUtc As DateTime = TimeZoneInfo.ConvertTimeToUtc(startDateOfThisMonth, tz) 
    Dim endUtc As DateTime = TimeZoneInfo.ConvertTimeToUtc(startDateOfNextMonth, tz) 
    

    或者,因爲你在你的數據庫使用datetimeoffset,你可以只建立在最後一步DateTimeOffset。掃描索引時,SQL將使用偏移量在內部轉換爲UTC。

    Dim start As DateTimeOffset = New DateTimeOffset(startDateOfThisMonth, 
                 tz.GetUtcOffset(startDateOfThisMonth)) 
    Dim end As DateTimeOffset = New DateTimeOffset(startDateOfNextMonth, 
                 tz.GetUtcOffset(startDateOfNextMonth)) 
    

當你查詢你的數據庫,使用table.dto >= @start AND table.dto < @end(一個半開區間)。

+0

非常酷和有趣的方法。感謝您的支持。現在就試試這個。我已經完成了所有的工作,但它仍然有點繁瑣和昂貴。 – user1447679

+0

這真是太棒了......所以,爲了完全清楚起見,如果我通過一個開始和/或結束的正面或負面的偏移量,SQL Server會照顧它嗎?這似乎是工作,但只是想確定。非常感謝。 – user1447679

+0

如果你的字段是'datetimeoffset',並且你的查詢參數也是'DateTimeOffset',那麼是的 - 在查詢過程中,SQL會將它標準化爲UTC。否則,您將首先自己轉換爲UTC。如果你喜歡,你仍然可以自己做,或者你不信任SQL來做。 ;) –