2009-07-10 8 views
8

Estoy usando DateTime.Now para mostrar algo de acuerdo con la fecha de hoy, y cuando se trabaja localmente (Malta, Europa) los tiempos aparecen correctamente (obviamente debido a la zona horaria) pero Por supuesto, cuando lo subo a mi servidor de alojamiento (EE. UU.), DateTime.Now no representa la zona horaria correcta.C#: Asegurándome de DateTime.Now devuelve un GMT + 1 vez

Por lo tanto, en mi código, ¿cómo puedo convertir DateTime.Now para devolver correctamente la hora de una zona horaria GMT + 1?

Respuesta

14

Utilice la clase TimeZoneInfo encontrado en el Sistema .Núcleo;

Debe establecer DateTimeKind en DateTimeKind.Utc para esto.

DateTime MyTime = new DateTime(1990, 12, 02, 19, 31, 30, DateTimeKind.Utc); 

DateTime MyTimeInWesternEurope = TimeZoneInfo.ConvertTimeBySystemTimeZoneId(MyTime, "W. Europe Standard Time"); 

¡Solo si usa .Net 3.5 though!

4

No creo que pueda establecer una propiedad en su código que haga que DateTime.Now devuelva algo más que la hora actual de la computadora en la que se ejecuta el código. Si quieres tener una manera de obtener siempre otra hora, probablemente necesites ajustar otra función. Puede puede hacer la ida y vuelta sobre la hora UTC y añadir el desplazamiento deseado:

private static DateTime GetMyTime() 
{ 
    return DateTime.UtcNow.AddHours(1); 
} 

(ejemplo de código actualizada tras el comentario de Lucas sobre el funcionamiento interno de DateTime.Now)

+0

Uso de 'DateTime.UtcNow.AddHours (1)' en lugar le ahorrará algo de tipeo – LukeH

+0

Sí, me di cuenta de eso. Pero entonces no estoy seguro de que hagan exactamente lo mismo; UtcNow recupera la hora del sistema y realiza algunas operaciones con "números mágicos", mientras que ToUniversalTime usa TimeZone.CurrentTimeZone para obtener el tiempo Utc. Supongo que siempre regresarán al mismo tiempo; o) –

+0

'DateTime.Now' usa' UtcNow' detrás de escena, por lo que su código original se traduce a algo como 'DateTime.UtcNow.ToLocalTime(). ToUniversalTime(). AddHours (1) '. – LukeH

14

Depende de lo que quiere decir con "una zona horaria GMT + 1". ¿Quiere decir permanentemente UTC + 1, o quiere decir UTC + 1 o UTC + 2 según DST?

Si está utilizando .NET 3.5, utilice TimeZoneInfo para tener una zona horaria correspondiente, a continuación, utilizar:

// Store this statically somewhere 
TimeZoneInfo maltaTimeZone = TimeZoneInfo.FindSystemTimeZoneById("..."); 
DateTime utc = DateTime.UtcNow; 
DateTime malta = TimeZoneInfo.ConvertTimeFromUtc(utc, maltaTimeZone); 

Tendrá que trabajar a cabo el ID del sistema para la zona horaria de Malta, pero puede hacerlo fácilmente mediante la ejecución de este código localmente:

Console.WriteLine(TimeZoneInfo.Local.Id); 

a juzgar por sus comentarios, este bit será irrelevante, pero sólo para los demás ...

Si tiene y no con .NET 3.5, tendrá que calcular el horario de luz usted mismo. Para ser sincero, la forma más fácil de hacer va a ser una tabla de búsqueda simple. Calcule los cambios del horario de verano para los próximos años y luego escriba un método simple para devolver el desplazamiento a una hora UTC particular con esa lista codificada. Es posible que sólo desea una ordenados List<DateTime> con los cambios conocidos en, y se alternan entre 1 y 2 horas hasta que su fecha es después del último cambio:

// Be very careful when building this list, and make sure they're UTC times! 
private static readonly IEnumerable<DateTime> DstChanges = ...; 

static DateTime ConvertToLocalTime(DateTime utc) 
{ 
    int hours = 1; // Or 2, depending on the first entry in your list 
    foreach (DateTime dstChange in DstChanges) 
    { 
     if (utc < dstChange) 
     { 
      return DateTime.SpecifyKind(utc.AddHours(hours), DateTimeKind.Local); 
     } 
     hours = 3 - hours; // Alternate between 1 and 2 
    } 
    throw new ArgumentOutOfRangeException("I don't have enough DST data!"); 
} 
+0

Jon, he editado tu respuesta para invertir los parámetros de TimeZoneInfo.ConvertTimeFromUtc –

+0

Whoops, gracias. Lo curioso es que en realidad los revisé primero, ¡y luego los puse al revés! –

+0

Su solución arroja esta excepción en el método ConvertTimeFromUtc: La conversión no se pudo completar porque el DateTime proporcionado no tenía la propiedad Kind configurada correctamente. Por ejemplo, cuando la propiedad Kind es DateTimeKind.Local, la zona horaria de origen debe ser TimeZoneInfo.Local. Nombre del parámetro: sourceTimeZone –

Cuestiones relacionadas