2010-12-06 121 views

回答

2

也回答在What every developer should know about time(其中包括引用的屏幕截圖)。

今天夏令時結束,我認爲這是一個好時機。如何處理時間是這些棘手的問題之一,它很容易讓它錯誤。所以讓我們潛入。(注意:我們在Windward Reports中實施調度系統時學到了這些經驗教訓。)

首先,使用UTC(也稱爲格林威治標準時間)很多次都不是正確的解決方案。然而,許多程序員認爲他們是否存儲所有的東西,然後他們已經覆蓋。 (這個錯誤是幾年前美國國會改變了DST開始的原因,因此你必須在Outlook上運行修補程序來調整重複發生的事件。)

因此,讓我們從關鍵問題開始 - 我們是什麼意思按時間?當用戶說他們想要在上午7點運行時,這意味着什麼?在大多數情況下,它們意味着他們所在的上午7點 - 但並非總是如此。在某些情況下,爲了準確地比較所說的Web服務器統計信息,他們希望每個「日」在同一時間結束,而不針對DST進行調整。另一方面,某人在一天中的某些時間吃藥,並在日曆中設置藥物時,會希望該時間始終處於當地時間,因此下午3點的活動並非凌晨3點左右,世界。

因此,我們有三個主要的用例這裏(有一些人,但他們一般可以通過以下處理):

1.相同的絕對(由於缺乏一個更好的詞)的時間。

2.在給定時區內,DST開/關(包括在某些地區出現的雙重DST)時發生移動。

3.當地時間。

第一個很容易處理 - 您將其設置爲UTC。通過這樣做,一年中的每一天將有24小時。 (有趣的是,UTC只與格林威治標準時間的時間相匹配,當它是DST時,格林威治和UTC不相同。)

第二個要求存儲時間和時區。但是,時區是地理區域,而不是當前偏移量(偏移量是與UTC的差值)。換句話說,您存儲「山地時間」,而不是「山地標準時間」或「山區夏令時間」。因此,無論一年中的哪個時間,科羅拉多州的「山區時間」上午7點都是上午7點。

第三個與第二個類似,它有一個稱爲「本地時間」的時區。但是,它需要知道它所處的時區,以確定它何時發生。

展望現在有辦法解決這個問題。單擊時區按鈕:

,現在您可以設置時區爲每個事件:

當我出差我用這包括在一個區域離開,而在另一個到達我的飛行時間。 Outlook將顯示本地時區中的所有內容,並在更改時進行調整。另一方面,iPhone不知道這是怎麼回事,當我在另一個時區旅行時(當你住在科羅拉多州時,幾乎每次旅行都到了另一個時區),所有東西都沒有。

把它使用

好了,你怎麼處理呢?這其實很簡單。每次需要存儲以下兩種方式之一:

1.按照UTC。通常,當以UTC格式存儲時,您仍然會在當地時間設置/顯示它。

2.作爲日期時間加上地理時區(可以是「本地時間」)。

現在的訣竅是知道要使用哪個。以下是一些一般規則。您需要了解其他用例,但大部分都屬於這些類別。

1.什麼時候發生 - UTC。這是一個單一的事件,無論用戶如何顯示,發生的時間都是不可改變的。

2.當用戶選擇UTC時區 - UTC時。

3.未來的事件,用戶希望它發生在時區 - 日期時間加上時區。現在使用UTC可能是安全的,如果它會在接下來的幾個月發生的話(改變時區通常會有這麼多的警告 - 雖然有時只有8天),但在某些時候你需要這樣做,所以你應該這樣做適用於所有情況。在這種情況下,你顯示你存儲的內容。

4.對於預定的事件,它何時會發生 - UTC。這是一個性能要求,您希望能夠在運行時之前獲得所有「下一個事件」。搜索日期比重新計算每個日期要快得多。但是,如果每個季度運行的事件的規則發生變化,則需要定期重新計算所有計劃的事件。

1.對於「當地時間」的事件,重新計算應該在用戶的時區變化時發生。如果事件在更改中被跳過,則需要立即進行。

.NET日期時間

跳水在到.NET,這意味着我們需要能夠獲得兩件事標準庫不提供:

1.創建一個DateTime在任何時區(DateTime僅支持您的本地時區和UTC)。

2.對於給定的日期,時間和地理時區,獲取UTC時間。這需要根據該日期的該區域的DST規則進行調整。

幸運的是,有一個解決方案。我們已經開源了DateTime時區功能的擴展。你可以在這裏下載WindwardTimeZone。這使用Windows中的註冊表設置來執行每個區域的所有計算,因此應保持最新。

瀏覽器疼痛

的一兩件事,我們還沒有想出是如何知道用戶的位置,如果他們正在使用的瀏覽器擊中我們的Web應用程序。對於大多數國家而言,地區可用於確定時區 - 但不適用於美國(6個區),加拿大或俄羅斯(11個區)。所以你必須要求用戶設置他們的時區 - 並在旅行時改變它。如果有人知道這個解決方案,請讓我知道。。

更新:我收到賈斯汀Bonnar以下(謝謝):

的document.getElementById( '了timezone_offset')值=新的日期()使用getTimezoneOffset();

使用這個加上下面提到的IP地址的地理位置的建議會讓你關閉。但它不是100%。時間偏移不會告訴你,例如,如果你是在亞利桑那州(他們&夏威夷不夏令時觀察員)VS太平洋/山(取決於夏令時)時區。雖然對於今天99%的用戶來說,情況也是如此,但你也依賴於javascript。

基於IP地址的地理位置也是如此。當我收到我們的演示下載表單有問題的報告時,我正在賓館。我們根據IP地址的地理位置預先填寫城市,州,&國家的表單。它說我在俄亥俄州克利夫蘭。所以,通常是正確的,但並非總是如此。

我的意思是我們可以使用偏移量,對於有多個時間偏移量(在給定日期)的情況,請跟蹤IP地址的地理位置。但我確實希望這些權力會在HTML請求發送的標題信息中添加tz =。

+1

您應該更新您的文章以包含DateTimeOffset(http://msdn.microsoft.com/en-us/library/system.datetimeoffset.aspx),它自.NET 2.0起就已經存在! – Gabe 2010-12-06 00:26:43

相關問題