2011-01-06 20 views
6

Estoy tratando de migrar una aplicación WPF a SilverLight 4. La aplicación WPF utiliza TimeZoneInfo.FindSystemTimeZoneById() y TimeZoneInfo.ConvertTimeFromUtc() para convertir DateTime de zona horaria específica en el DateTime de otra hora específica zona.silverlight Time Zone convirtiendo

Pero no puedo encontrar ninguna de estas funciones en SilverLight 4. SilverLight parece ser compatible con la conversión de zona horaria entre Utc y Local solamente.

¿Hay alguna manera de convertir DateTime de cualquier zona horaria a cualquier otra zona horaria en SilverLight?

Respuesta

2

Desafortunadamente, actualmente no existe una funcionalidad estándar para hacerlo.

Permite comprobar (utilizando el reflector) cómo funciona el método TimeZoneInfo.FindSystemTimeZoneById(). Solo se necesita uno de los valores del 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; 
    } 
} 

Este campo almacena todos disponibles TimeZoneInfo-s. Y cuando llamas a FindSystemTimeZoneById (id) simplemente escoge un valor del diccionario prellenado. No sé cuándo se inicializa este diccionario y qué valores usa para la inicialización. Pero chico de this thread dijo que TimeZoneInfo usa los valores del registro: HKEY_LOCAL_MACHINE \ Software \ Microsoft \ Windows NT \ CurrentVersion \ Time Zones

La forma más obvia es crear su propio diccionario de diccionario y llenarlo con valores. Algo como esto:

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

Pero hay otro problema: TimeZoneInfo constructor es privado. Por lo tanto, si desea usar la funcionalidad FindSystemTimeZoneById() y ConvertTimeFromUtc(), debe implementarla desde cero. Cree una clase que represente la zona horaria, cree y complete el diccionario de esta clase con información de zonas horarias, etc. ...
No son buenas noticias, lo sé. Pero espero que sea útil para ti :)

0

En caso de que alguien se ejecuta a través de este hilo, aquí es lo que he encontrado ...

El código fuente de referencia de Microsoft para TimeZoneInfo (en la versión completa de .NET 4 CLR) incluye un método TryGetTimeZoneByRegistryKey(), que obtiene los husos horarios de la clave de registro HKLM\Software\Microsoft\Windows NT\CurrentVersion\Time Zones.

Supongo que si estuviera escribiendo una aplicación confiable de Silverlight, podría usar P/Invoke para hacer la búsqueda de registro.

Para nuestra aplicación, no queremos mostrar el cuadro de diálogo pidiendo permisos de plena confianza. Hice un poco más de búsqueda y encontré Stephane Delcroix's open-source implementation - No estoy seguro de si hay una fuente más oficial que ese enlace. Funciona con el formato de base de datos de zona horaria de Unix (zoneinfo), que puede download desde IANA.

La base de datos de la zona horaria es bastante grande y engordaría el tamaño de una aplicación de Silverlight si la incluyese. Pero solo necesitamos admitir algunas zonas horarias. Tomé un subconjunto de la base de datos y lo empaqué en nuestra aplicación Silverlight como recurso; luego modifiqué el código de Stephane para leer de un flujo de recursos en lugar de hacerlo desde el sistema de archivos. Tuve que eliminar toda la funcionalidad de tiempo local, ya que no hay/etc/localtime. Pero solo necesitábamos zonas horarias con nombre y la capacidad de convertir entre estas zonas horarias y UTC. Este enfoque parece funcionar bien.

+0

Hmm. En realidad, no utilicé la descarga de IANA. Acabo de copiar el contenido de/etc/zoneinfo de la máquina Linux más cercana de nuestra red. Resulta que los archivos IANA están en formato de texto, y debe ejecutarlos a través de un compilador de zona horaria ("zic"). La fuente "zic" también está en la misma página de IANA; pero supongo que es más fácil usar los binarios si tienes una máquina Linux para obtenerlos. –

+0

Aquí hay una [versión en GitHub] (https://github.com/mono/mono/tree/master/mcs/class/System.Core/System). –

1

Un poco tarde, pero lo hice hace un tiempo y lo publiqué en el sitio de la comunidad de MS para que lo usen las personas porque siempre se lo preguntaron.No hice la búsqueda de identificadores de zona horaria, pero utilicé el método FromSerializedString() dentro de mi aplicación SL. Mis servicios web pasarían los datos de ToSerializedString() como una propiedad de cadena y en SL solo consumiría este objeto según sea necesario. Hice un reflector del objeto TimeZoneInfo.

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

No estoy seguro si esto le ayuda (o cualquier lector futuro de este post).

Fue divertido de hacer, y resolvió mi problema. Estaba usando esto para V3 Silverlight, por lo que debería ser bueno para 4/5, pero también podría ser mejorado por Microsoft.

Actualizado el 2017-04-12: Enlace a GitHub, usando esto en una lib de PCL. Debería funcionar para SL, pero lo abandonamos como MS hace años.

+1

Hubiera sido genial pero el enlace está muerto ahora ... –

+0

Se actualizó para usar el enlace de Github. – TravisWhidden