2011-01-06 19 views
6

Sto provando a migrare un'app WPF a SilverLight 4. L'app WPF utilizza TimeZoneInfo.FindSystemTimeZoneById() e TimeZoneInfo.ConvertTimeFromUtc() per convertire DateTime del fuso orario specifico nel DateTime di un altro momento specifico zona.conversione fuso orario Silverlight

Ma non riesco a trovare nessuna di queste funzioni in SilverLight 4. SilverLight sembra supportare la conversione del fuso orario solo tra Utc e Local.

C'è un modo per convertire DateTime da qualsiasi fuso orario in qualsiasi altro fuso orario in SilverLight?

risposta

2

Purtroppo al momento non v'è alcuna funzionalità standard di farlo.

Consente di verificare (utilizzando il riflettore) come funziona il metodo TimeZoneInfo.FindSystemTimeZoneById(). Ci vuole solo uno dei valori da campo 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; 
    } 
} 

Questo campo memorizza tutti disponibili TimeZoneInfo-s. E quando chiami FindSystemTimeZoneById (id) ha appena preso un certo valore dal dizionario precompilato. Non so quando questo dizionario viene inizializzato e quali valori utilizza per l'inizializzazione. Ma il tizio da this thread ha detto che TimeZoneInfo utilizza valori dal registro: HKEY_LOCAL_MACHINE \ Software \ Microsoft \ Windows NT \ CurrentVersion \ Fusi orari

Il modo più ovvio è creare il dizionario del dizionario e riempirlo di valori. Qualcosa di simile a questo:

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

Ma c'è un altro problema: TimeZoneInfo costruttore è privato. Quindi, se si desidera utilizzare FindSystemTimeZoneById() e ConvertTimeFromUtc() funzionalità allora si dovrebbe implementare da molto zero. Creare una classe che rappresenta il fuso orario, creare e compilare dizionario di questa classe con fusi orari informazioni e così via ...
Non una buona notizia, lo so. Ma spero che sarà utile per voi :)

0

Nel caso qualcuno attraversa questa discussione, ecco cosa ho trovato ...

Il codice sorgente di riferimento Microsoft per TimeZoneInfo (nella versione completa di .NET 4 CLR) include un metodo TryGetTimeZoneByRegistryKey(), che ottiene i fusi orari dal registro di sistema chiave HKLM\Software\Microsoft\Windows NT\CurrentVersion\Time Zones.

Suppongo che se si stesse scrivendo un'app di Silverlight attendibile, è possibile utilizzare P/Invoke per eseguire la ricerca del registro.

Per la nostra applicazione, non vogliamo mostrare la finestra di dialogo per chiedere le autorizzazioni complete di fiducia. Ho fatto qualche altra ricerca e ho trovato Stephane Delcroix's open-source implementation - Non sono sicuro che ci sia una fonte più ufficiale di quel link. Funziona con il tempo formato di database di zona Unix (zoneinfo), che è possibile download da IANA.

Il database dei fusi orari è piuttosto grande e se la si includesse si ridurrebbe la dimensione di un'app Silverlight. Ma abbiamo solo bisogno di supportare alcuni fusi orari. Ho preso un sottoinsieme del database e l'ho inserito nella nostra app Silverlight come risorsa; poi ho modificato il codice di Stephane per leggere da un flusso di risorse piuttosto che dal filesystem. Ho dovuto rimuovere tutte le funzionalità dell'ora locale, dato che non esiste/etc/localtime. Ma avevamo solo bisogno di fusi orari denominati e la possibilità di convertire tra questi fusi orari e UTC. Questo approccio sembra funzionare correttamente.

+0

Hmm. Non ho effettivamente utilizzato il download IANA - ho appena copiato il contenuto di/etc/zoneinfo dalla macchina Linux più vicina sulla nostra rete. Risulta che i file IANA sono in formato testo e devi eseguirli attraverso un compilatore di fuso orario ("zic"). Anche la sorgente "zic" si trova sulla stessa pagina IANA; ma suppongo che sia più facile usare i binari se si ha una macchina Linux da cui attingere. –

+0

Ecco una [versione su GitHub] (https://github.com/mono/mono/tree/master/mcs/class/System.Core/System). –

1

Un po 'tardi, ma l'ho fatto un po' di tempo fa e l'ho postato sul sito della comunità MS perché le persone lo usassero perché veniva sempre chiesto.Non ho eseguito la ricerca degli ID fuso orario, ma ho utilizzato il metodo FromSerializedString() all'interno della mia app SL. I miei servizi Web passerebbero i dati ToSerializedString() come proprietà stringa e in SL vorrei semplicemente utilizzare questo oggetto secondo necessità. Ho fatto un riflettore dell'oggetto TimeZoneInfo.

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

Non sono sicuro se questo ti aiuta (o qualsiasi lettore futuro di questo post).

È stato divertente, e ho risolto il mio problema. Stavo usando questo per V3 Silverlight, quindi dovrebbe essere buono per 4/5, ma potrebbe già essere migliorato da Microsoft.

Aggiornamento 2017-04-12: collegamento a GitHub, utilizzando questo in una lib di PCL. Dovrebbe funzionare per SL, ma abbiamo lasciato cadere ciò che MS ha fatto anni fa.

+1

Sarebbe stato fantastico ma il collegamento è morto ora ... –

+0

Aggiornato per utilizzare invece il collegamento Github. – TravisWhidden