2010-06-02 37 views
57

Estoy tratando de utilizar DateTimeOffset para transmitir un momento específico en el tiempo en cualquier zona horaria. No puedo entender cómo usar TimeZoneInfo para lidiar con el horario de verano.¿Cómo se usa TimeZoneInfo para obtener la hora local durante el horario de verano?

var dt = DateTime.UtcNow; 
Console.WriteLine(dt.ToLocalTime()); 

var tz = TimeZoneInfo.FindSystemTimeZoneById("Central Standard Time"); 
var utcOffset = new DateTimeOffset(dt, TimeSpan.Zero); 
Console.WriteLine(utcOffset.ToOffset(tz.BaseUtcOffset)); 

Esto muestra:

6/2/2010 4:37:19 PM 
6/2/2010 3:37:19 PM -06:00 

estoy en la zona horaria central, y y en este momento estamos en el horario de verano. Estoy tratando de obtener la segunda línea de la manera siguiente:

6/2/2010 4:37:19 PM -05:00 

BaseUtcOffset aparentemente no cambia basado en el horario de verano.

¿Cómo puedo obtener el momento adecuado con el valor de compensación correcto?

+9

+1 - Me vuelve loco que TimeZoneInfo.ConvertTimeBySystemTimeZoneId no solo trabaja para este :) –

Respuesta

47

que necesita para obtener la UTCOFFSET del TimeZoneInfo, a continuación, pasar a la que ToOffset() Método:

var dt = DateTime.UtcNow; 
Console.WriteLine(dt.ToLocalTime()); 

var tz = TimeZoneInfo.FindSystemTimeZoneById("Central Standard Time"); 
var utcOffset = new DateTimeOffset(dt, TimeSpan.Zero); 
Console.WriteLine(utcOffset.ToOffset(tz.GetUtcOffset(utcOffset))); 
+0

veo ... usted tiene que conseguir el desplazamiento para esa fecha específica en UTC la zona horaria gracias. – jaminto

+3

Esta no es la mejor manera en comparación con [la respuesta de Karl Gjertsen] (http://stackoverflow.com/a/16789973/57611) que usa una sola función .Net para hacer el trabajo en lugar de extraer el desplazamiento creando un nuevo, descarta 'DateTimeOffset'. – ErikE

35

También puede utilizar TimeZoneInfo.ConvertTimeFromUtc, lo que permitirá al horario de verano:

DateTime utc = DateTime.UtcNow; 
TimeZoneInfo zone = TimeZoneInfo.FindSystemTimeZoneById("Central Standard Time"); 
DateTime localDateTime = TimeZoneInfo.ConvertTimeFromUtc(utc, zone); 
5

O mejor, si no desea codificar el identificador de zona tiempo:

TimeZoneInfo tzi = TimeZoneInfo.FindSystemTimeZoneById(TimeZoneInfo.Local.Id); 
DateTime localDateTime = TimeZoneInfo.ConvertTimeFromUtc(DateTime.UtcNow, tzi); 
+0

¿No podría simplemente usar 'TimeZoneInfo.Local' directamente? ¿Por qué necesita la llamada a 'FindSystemTimeZoneById'? – CoderDennis

+1

Tienes razón, no lo necesitamos. Podemos hacerlo así 'DateTime localDateTime = TimeZoneInfo.ConvertTimeFromUtc (networkDateTime, TimeZoneInfo.Local); ' – Pabinator

+0

Pero luego se lo fija a una zona horaria única. Depende de cómo quieras usar el código, supongo. :-) –

1

Soy un principiante tanto en .NET y stackoverflow, por lo que podría estar equivocado, pero aquí va:

Usando TimeZoneInfo.ConvertTimeFromUtc permitirá al horario de verano, y convertir a la hora correcta según el tiempo zona + un posible desplazamiento DST. Sin embargo, el desplazamiento en sí en el objeto resultante mostrará el desplazamiento para la hora estándar y no tendrá en cuenta el horario de verano. Por lo tanto, si desea hacer un ToString en el objeto, terminará con la hora correcta (en horas y minutos), pero con el desplazamiento incorrecto durante el horario de verano, lo que puede ocasionar un momento incorrecto más adelante en el código.

Si en su lugar usa GetUtcOffset para obtener el desplazamiento durante un tiempo específico, y luego realiza un ToOffset en el objeto DateTimeOffset, tanto las horas/minutos como el desplazamiento se convertirán correctamente y podrá hacer un ToString con seguridad .

string ExpectedDateTimePattern = "yyyy'-'MM'-'dd'T'HH':'mm':'ss''zzz"; 
string timeZoneId = "FLE Standard Time"; 
string dateTimestr = "2017-10-09T09:00:00+02:00"; 

DateTimeOffset dto = DateTimeOffset.Parse(dateTimeStr); 
TimeZoneInfo zone = TimeZoneInfo.FindSystemTimeZoneById(timeZoneId); 
TimeSpan offset = zone.GetUtcOffset(dto); 
dto = dto.ToOffset(offset); 
string localTime = dto.ToString(ExpectedDateTimePattern); 

localTime devolverá "2017-10-09T10: 00: 00 + 03: 00".

Cuestiones relacionadas