2011-01-06 90 views
6

我在嘗試將WPF應用程序遷移到SilverLight 4. WPF應用程序使用TimeZoneInfo.FindSystemTimeZoneById()和TimeZoneInfo.ConvertTimeFromUtc()將特定時區的DateTime轉換爲另一個特定時間的DateTime區。silverlight時區轉換

但我在SilverLight 4中找不到這兩個函數中的任何一個.SilverLight似乎只支持Utc和Local之間的時區轉換。

有沒有辦法將日期時間從任何時區轉換爲SilverLight中的任何其他時區?

回答

2

不幸的是,目前沒有標準的功能來做到這一點。

允許檢查(使用反射器)TimeZoneInfo.FindSystemTimeZoneById()方法的工作方式。它只是需要值中的一個s_systemTimeZones場:

private static Dictionary<string, TimeZoneInfo> s_systemTimeZones 
{ 
    get 
    { 
     if (s_hiddenSystemTimeZones == null) 
     { 
      s_hiddenSystemTimeZones = new Dictionary<string, TimeZoneInfo>(); 
     } 
     return s_hiddenSystemTimeZones; 
    } 
    set 
    { 
     s_hiddenSystemTimeZones = value; 
    } 
} 

此字段存儲所有可用的TimeZoneInfo-S。而當你調用FindSystemTimeZoneById(id)時,它只是從預填字典中選擇了一些值。我不知道這個字典何時初始化以及它用於初始化的值。但來自this thread的人告訴說,TimeZoneInfo使用來自注冊表的值:HKEY_LOCAL_MACHINE \ Software \ Microsoft \ Windows NT \ CurrentVersion \ Time Zones

最明顯的方法是創建自己的詞典並填充它的值。類似這樣的:

Dictionary<string, TimeZoneInfo> dictionary = new Dictionary<string, TimeZoneInfo>(); 
TimeZoneInfo info = new TimeZoneInfo("ID", new TimeSpan(0, 1, 0, 0), "SomeCultureName", "Some Standard Time", "Some Daylight Time", null, true); 
dictionary.Add("Some time", info); 

但還有另一個問題:TimeZoneInfo構造函數是私有的。所以如果你想使用FindSystemTimeZoneById()和ConvertTimeFromUtc()功能,那麼你應該從零開始實現它。創建一些代表時區的課程,用時區信息創建和填寫此課程的詞典等...
不是很好的消息,我知道。但我希望它會爲你:)

0

如果有人碰到這個線程中運行,這裏是我發現有用...

爲的TimeZoneInfo微軟參考源代碼(在完整的.NET 4 CLR)包含一個TryGetTimeZoneByRegistryKey()方法,該方法從註冊表項HKLM\Software\Microsoft\Windows NT\CurrentVersion\Time Zones獲取時區。

我猜如果你正在編寫一個可信的Silverlight應用程序,你可以使用P/Invoke來完成註冊表查找。

對於我們的應用程序,我們不希望顯示詢問完全信任權限的對話框。我做了一些更多的搜索,發現Stephane Delcroix's open-source implementation - 我不確定是否有比該鏈接更官方的來源。它適用於Unix時區數據庫格式(zoneinfo),您可以從IANA獲得download

時區數據庫非常大,如果包含Silverlight應用程序,它會膨脹大小。但我們只需要支持幾個時區。我將數據庫的一個子集作爲資源打包到我們的Silverlight應用程序中;然後我修改了Stephane的代碼,從資源流中讀取,而不是從文件系統中讀取。由於沒有/ etc/localtime,我必須刪除所有本地時間功能。但我們只需要命名時區,並且能夠在這些時區和UTC之間進行轉換。這種方法似乎行得通。

+0

嗯。我沒有真正使用IANA下載 - 我只是從我們網絡上最近的Linux機器複製了/ etc/zoneinfo的內容。事實證明,IANA文件是文本格式的,您必須通過時區編譯器(「zic」)運行它們。 「zic」來源也位於同一IANA頁面上;但是我想如果你有一臺Linux機器來使用二進制文件,那麼它更容易使用。 – 2012-03-31 01:08:27

+0

這是[GitHub上的版本](https://github.com/mono/mono/tree/master/mcs/class/System.Core/System)。 – 2012-03-31 01:14:44

1

有點晚了,但我做了一段時間後,並把它貼在MS社區網站上供人們使用,因爲它總是被問到。我沒有做時區ID查找,但是我在我的SL應用程序中使用了FromSerializedString()方法。我的Web服務會將ToSerializedString()數據作爲字符串屬性傳遞,並且在SL中,我將根據需要使用此對象。我做了TimeZoneInfo對象的反射器。

https://github.com/TWhidden/DevStuff/blob/master/StackOverflow/TimeZoneInfo.cs

不知道這是否可以幫助你(或任何未來的這個帖子的讀者)。

這很有趣,並解決了我的問題。我在V3 Silverlight中使用這個版本,所以它對4/5應該是好的,但微軟已經可以改進它了。

更新2017-04-12:鏈接到GitHub,在PCL庫中使用它。應該爲SL工作,但我們放棄了像MS在幾年前做的那樣。