2013-05-30 45 views
2

我試圖在C#應用程序中控制夏令時,而不是讓Windows執行此操作。 (我在這裏不會介紹原因)。TimeZoneInfo浪漫標準時間需要一小時之前曖昧

所以我已刪除勾選「自動調整夏令時時鐘」的日期和時間設置(Windows7的)

我已經爲了證明,我面臨的問題寫了這一小段代碼。

TimeZoneInfo tzi = TimeZoneInfo.FindSystemTimeZoneById(TimeZoneInfo.Local.Id); 
                // "Romance Standard Time" 
var rule = tzi.GetAdjustmentRules()[0]; 

System.Globalization.CultureInfo.CurrentCulture.ClearCachedData(); 
var timestampToWorkOn = DateTime.Now; 
Console.WriteLine("Timezone is: " + tzi.ToString()); 
Console.WriteLine("Timezone id is: " + tzi.Id); 
Console.WriteLine("Timestamp right now: " + timestampToWorkOn.ToString("yyyy-MM-dd HH:mm")); 
Console.WriteLine("Rule for change says: " + rule.DaylightTransitionEnd.TimeOfDay.ToString("HH:mm")); 
Console.WriteLine("Is it dst: " + tzi.IsDaylightSavingTime(timestampToWorkOn)); 
Console.WriteLine("Is it ambiguous:" + tzi.IsAmbiguousTime(timestampToWorkOn)); 

至於從DST正常時間的過渡應該在3:00發生我會懷疑,從2:00到3:00的時間將是不明確的。 但是從1:54運行代碼的結果是:

時區爲:(UTC + 01:00)布魯塞爾,哥本哈根,馬德里,巴黎
區ID是:浪漫標準時間
時間戳權現在:2013年10月27日01:54
規則變革說:03:00
它是DST:假
它是模棱兩可:真

我可能失去了一些東西。 我認爲dst是真實的,含糊不清是錯誤的,但它卻是相反的。

很難保持概述,但爲什麼我看到這種行爲?

+0

選擇夏令時改變的確切日期無疑是問題的一部分。拋出「我會自己做」角度和UTC + 1偏移量來任意地爲問題添加一小時。通過專門以UTC工作,讓傷害停止。 –

+0

但目標是控制窗戶的時間。包括dst轉換。如果我想用純粹的utc工作,並且我想實現控制時間轉換的目標,那麼我需要一個包含所有時區的所有規則的數據庫.....並維護它。我想我可能想仔細看看諾達時間。 .... –

+0

你想創建Iversen標準時間嗎?這實際上是可能的,TimeZoneInfo.CreateCustomTimeZone()。說服其他程序使用它可能會成爲一個問題。 –

回答

0

您應該閱讀this blog post,其中詳細描述了Windows註冊表設置如何受時區選擇和「自動調整...」複選框的影響。還介紹TimeZoneInfo如何使用這些設置。具體來說,它指出:

當夏令時間本地時區禁用,TimeZoneInfo.Local將返回的TimeZoneInfo對象與TimeZoneInfo.SupportsDaylightSavingTime設置爲false。使用此TimeZoneInfo實例的任何TimeZoneInfo.ConvertTime(...)調用都不會考慮夏令時。

恕我直言,從來沒有一個很好的理由來清除該複選框並禁用DST。它將電腦的時鐘置於人爲的現實中。

如果您在服務器上運行代碼,則應該將服務器的時區設置爲UTC。這將使Windows不必更新計算機的BIOS進行轉換,並且會讓來自其他服務器的本地時間戳全部排隊。

關於您的代碼,請認識到DateTime.Now的結果具有.Kind == DateTimeKind.Local,並且與您之前使用的時區沒有關係。你碰巧報告的是當地時區,但如果你使用了不同的代碼,你的代碼將會不正確。

當您得到調整規則時,假設當地時區將有一個。有些(如亞利桑那州)沒有任何DST,所以他們沒有調整規則,並且你得到一個超出界限的例外(因爲[0])。

而且,只是被挑剔,但是,

// This line is self redundant. 
TimeZoneInfo tzi = TimeZoneInfo.FindSystemTimeZoneById(TimeZoneInfo.Local.Id); 

// It can be reduced to: 
TimeZoneInfo tzi = TimeZoneInfo.Local; 

但真正的問題是,因爲你有「調整爲夏令時」選項關閉,日期時間不被轉換爲正確的UTC時刻,爲了如果不明確或不明確,則作出判斷。如果您深入到.Net源代碼(反編譯或symbolsource)DateTime.IsAmbiguousTime(),您會發現它使用TimeZoneInfo.ConvertTime(),其中(根據前面的報價)未選中框時未考慮DST,從而導致結果不正確(基本上1小時)。

您還應該查看TimeZoneInfo.IsAmbiguousTime的MSDN說明,該說明描述了輸入的Kind如何影響輸出結果。