2011-01-06 10 views
6

Próbuję przenieść aplikację WPF do SilverLight 4. Aplikacja WPF korzysta z TimeZoneInfo.FindSystemTimeZoneById() i TimeZoneInfo.ConvertTimeFromUtc() do konwersji DateTime specyficznej strefy czasowej na DateTime innego określonego czasu strefa.Konwersja strefy czasowej silverlight

Ale nie mogę znaleźć żadnej z tych funkcji w SilverLight 4. SilverLight wydaje się obsługiwać strefę czasową konwertować między tylko Utc i Local.

Czy istnieje sposób na konwersję DateTime z dowolnej strefy czasowej do innej strefy czasowej w SilverLight?

Odpowiedz

2

Niestety obecnie nie ma standardowej funkcjonalności do tego.

Umożliwia sprawdzenie (za pomocą reflektora), w jaki sposób działa metoda TimeZoneInfo.FindSystemTimeZoneById(). To zajmuje tylko jedną z wartości z pola 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; 
    } 
} 

To pole przechowuje wszystkie dostępne TimeZoneInfo-S. A kiedy zadzwonisz do FindSystemTimeZoneById (id), po prostu wybrałeś wartość ze wstępnie wypełnionego słownika. Nie wiem, kiedy ten słownik się uruchamia i jakie wartości używa do inicjowania. Ale facet z this thread powiedział, że TimeZoneInfo użyć wartości z rejestru: HKEY_LOCAL_MACHINE \ Software \ Microsoft \ Windows NT \ CurrentVersion \ strefy czasowe

Najbardziej oczywistym sposobem jest stworzenie własnego słownika słownika i wypełnić go z wartościami. Coś takiego:

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); 

Ale jest jeszcze jeden problem: konstruktor TimeZoneInfo jest prywatny. Więc jeśli chcesz użyć funkcji FindSystemTimeZoneById() i ConvertTimeFromUtc(), powinieneś zaimplementować ją od zera. Utwórz klasę reprezentującą strefę czasową, utwórz i wypełnij słownik tej klasy informacjami o strefach czasowych i tak dalej ...
Niezbyt dobra wiadomość, wiem. Ale mam nadzieję, że będzie użyteczny dla ciebie :)

0

W przypadku ktoś biegnie w poprzek tego wątku, oto co znalazłem ...

Kod źródłowy odniesienie Microsoft dla TimeZoneInfo (w pełnej .NET 4 CLR) zawiera metodę TryGetTimeZoneByRegistryKey(), która pobiera strefy czasowe z klucza rejestru HKLM\Software\Microsoft\Windows NT\CurrentVersion\Time Zones.

Zgaduję, że jeśli piszesz zaufaną aplikację Silverlight, możesz użyć P/Invoke do wyszukiwania rejestru.

Dla naszej aplikacji nie chcemy wyświetlać okna dialogowego z prośbą o pełne uprawnienia zaufania. Zrobiłem więcej wyszukiwania i znalazłem Stephane Delcroix's open-source implementation - Nie jestem pewien, czy istnieje bardziej oficjalne źródło niż ten link. Działa z uniksowym formatem bazy danych strefy czasowej (zoneinfo), który można download z IANA.

Baza danych strefy czasowej jest dość duża i zwiększyłaby rozmiar aplikacji Silverlight, jeśli została uwzględniona. Musieliśmy jednak obsługiwać tylko kilka stref czasowych. Wziąłem podzbiór bazy danych i zapakowałem go do naszej aplikacji Silverlight jako zasób; następnie zmodyfikowałem kod Stephane'a, by odczytać go ze strumienia zasobów, a nie z systemu plików. Musiałem usunąć wszystkie funkcje czasu lokalnego, ponieważ nie ma/etc/localtime. Ale potrzebowaliśmy tylko nazwanych stref czasowych i możliwości konwersji między tymi strefami czasowymi a czasem UTC. Takie podejście wydaje się działać dobrze.

+0

Hmm. W rzeczywistości nie korzystałem z pobierania IANA - właśnie skopiowałem zawartość/etc/zoneinfo z najbliższego komputera z systemem Linux w naszej sieci. Okazuje się, że pliki IANA są w formacie tekstowym i trzeba je uruchomić przez kompilator strefy czasowej ("zic"). Źródło "zic" znajduje się również na tej samej stronie IANA; ale myślę, że łatwiej jest używać plików binarnych, jeśli masz maszynę Linux, aby je pobrać. –

+0

Oto [wersja na GitHub] (https://github.com/mono/mono/tree/master/mcs/class/System.Core/System). –

1

Trochę za późno, ale zrobiłem to chwilę i wysłałem na stronę społeczności MS, aby ludzie mogli z niej korzystać, ponieważ zawsze o to pytano.Nie szukałem identyfikatorów stref czasowych, ale użyłem metody FromSerializedString() w mojej aplikacji SL. Moje usługi sieciowe przekazywałyby dane ToSerializedString() jako właściwość typu string, aw SL po prostu używałem tego obiektu w razie potrzeby. Zrobiłem reflektor obiektu TimeZoneInfo.

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

Nie wiem, czy to pomaga (lub jakikolwiek przyszły czytelnik tego postu).

Było fajnie robić i rozwiązać mój problem. Używałem tego dla V3 Silverlight, więc powinno to być dobre dla 4/5, ale może być już ulepszone przez Microsoft.

Zaktualizowano 2017-04-12: Link do GitHub, używając tego w bibliotece PCL. Powinienem pracować dla SL, ale zrzuciliśmy to jak MS lat temu.

+1

Byłoby świetnie, ale link jest już martwy ... –

+0

Zaktualizowany do używania linku Github zamiast tego. – TravisWhidden

Powiązane problemy