Estamos desarrollando una aplicación C # para un cliente de servicio web. Esto se ejecutará en PC con Windows XP.
Uno de los campos devueltos por el servicio web es un campo DateTime. El servidor devuelve un campo en formato GMT, es decir, con una "Z" al final.
Sin embargo, encontramos que .NET parece hacer algún tipo de conversión implícita y el tiempo siempre fue de 12 horas.
El siguiente ejemplo de código resuelve esto hasta cierto punto porque la diferencia de 12 horas se ha ido pero no permite el horario de verano de Nueva Zelanda.
CultureInfo ci = new CultureInfo("en-NZ");
string date = "Web service date".ToString("R", ci);
DateTime convertedDate = DateTime.Parse(date);
Según este sitio de fecha :
Compensación UTC / GMT
Zona horaria estándar: UTC / GMT +12 horas
Horario de verano: +1 hora
Compensación de zona horaria actual: UTC / GMT +13 horas
¿Cómo nos ajustamos para la hora extra? ¿Se puede hacer esto mediante programación o es algún tipo de configuración en las PC?
Z
tiempo se refiere a UTC, no a GMT. Los dos pueden diferir en hasta 0.9 segundos.Respuestas:
Para cadenas como
2012-09-19 01:27:30.000
,DateTime.Parse
no se puede decir de qué zona horaria son la fecha y la hora.DateTime
tiene una propiedad Kind , que puede tener una de las tres opciones de zona horaria:NOTA Si desea representar una fecha / hora que no sea UTC o su zona horaria local, entonces debe usar
DateTimeOffset
.Entonces, para el código en su pregunta:
Dices que sabes de qué tipo es, así que dilo.
Ahora, una vez que el sistema sabe que es en hora UTC, puede llamar
ToLocalTime
:Esto le dará el resultado que necesita.
fuente
DateTime convertedTime = new DateTime(DateTime.Parse(dateStr).Ticks), DateTimeKind.Utc);
Kind
deDateTime
deUnspecified
aUTC
es innecesario.Unspecified
se supone que esUTC
para los propósitos deToLocalTime
: msdn.microsoft.com/en-us/library/…Examinaría el uso de la clase System.TimeZoneInfo si está en .NET 3.5. Ver http://msdn.microsoft.com/en-us/library/system.timezoneinfo.aspx . Esto debe tener en cuenta los cambios de horario de verano correctamente.
fuente
fuente
DateTime
los objetos tienen elKind
deUnspecified
por defecto, que a los efectos deToLocalTime
se supone que esUTC
.Para obtener la hora local de un
Unspecified
DateTime
objeto, solo necesita hacer esto:El paso de cambiar el
Kind
deDateTime
deUnspecified
aUTC
es innecesario.Unspecified
se supone que esUTC
para los fines deToLocalTime
: http://msdn.microsoft.com/en-us/library/system.datetime.tolocaltime.aspxfuente
convertedDate.FromLocalTime();
se convertirá aUTC
.Sé que esta es una pregunta anterior, pero me encontré con una situación similar y quería compartir lo que había encontrado para futuros buscadores, posiblemente incluyéndome a mí mismo :).
DateTime.Parse()
puede ser complicado - mira aquí por ejemplo.Si
DateTime
proviene de un servicio web o de alguna otra fuente con un formato conocido, es posible que desee considerar algo comoo mejor,
La
AssumeUniversal
bandera le dice al analizador que la fecha / hora ya es UTC; la combinación deAssumeUniversal
yAdjustToUniversal
le dice que no convierta el resultado a la hora "local", lo que intentará hacer de forma predeterminada. (Personalmente, trato de tratar exclusivamente con UTC en la (s) capa (s) de negocio / aplicación / servicio de todos modos. Pero omitir la conversión a la hora local también acelera las cosas: un 50% o más en mis pruebas, ver más abajo).Esto es lo que estábamos haciendo antes:
Habíamos perfilado la aplicación y descubrimos que DateTime.Parse representaba un porcentaje significativo del uso de la CPU. (Por cierto, el
CultureInfo
constructor no fue contribuyó significativamente al uso de la CPU).Así que configuré una aplicación de consola para analizar una cadena de fecha / hora 10000 veces de varias maneras. Línea inferior:
Parse()
10 segundosParseExact()
(convirtiendo a local) 20-45 msParseExact()
(no convirtiendo a local) 10-15 ms... y sí, los resultados
Parse()
están en segundos , mientras que los demás están en milisegundos .fuente
Solo me gustaría agregar una nota general de precaución.
Si todo lo que está haciendo es obtener la hora actual del reloj interno de la computadora para poner una fecha / hora en la pantalla o un informe, entonces todo está bien. Pero si está guardando la información de fecha / hora para referencia posterior o está calculando fecha / hora, ¡tenga cuidado!
Supongamos que determina que un crucero llegó a Honolulu el 20 de diciembre de 2007 a las 15:00 UTC. Y quieres saber qué hora local era esa.
1. Probablemente hay al menos tres 'locales' involucrados. Local puede significar Honolulu, o puede significar dónde se encuentra su computadora, o puede significar la ubicación donde se encuentra su cliente.
2. Si utiliza las funciones integradas para realizar la conversión, probablemente sea incorrecto. Esto se debe a que el horario de verano está (probablemente) actualmente vigente en su computadora, pero NO estuvo vigente en diciembre. Pero Windows no sabe esto ... todo lo que tiene es una bandera para determinar si el horario de verano está actualmente vigente. Y si está actualmente vigente, felizmente agregará una hora incluso a una fecha en diciembre.
3)El horario de verano se implementa de manera diferente (o nada) en varias subdivisiones políticas. No piense que solo porque su país cambia en una fecha específica, también lo harán otros países.
fuente
fuente
No olvide que si ya tiene un objeto DateTime y no está seguro de si es UTC o Local, es bastante fácil usar los métodos directamente en el objeto:
A menos que se especifique .net usará la configuración local de la PC. Leería: http://msdn.microsoft.com/en-us/library/system.globalization.daylighttime.aspx
Por lo que parece, el código podría verse más o menos así:
Y como se mencionó anteriormente, verifique en qué configuración de zona horaria está su servidor. Hay artículos en la red sobre cómo afectar de manera segura los cambios en IIS.
fuente
En respuesta a la sugerencia de Dana:
El código de muestra ahora se ve así:
La fecha original era 20/08/08; el tipo era UTC
Tanto "convertDate" como "dt" son iguales:
21/08/08 10:00:26; el tipo era local
fuente
Tuve el problema de que estaba en un conjunto de datos que se empujaba a través del cable (servicio web al cliente) que cambiaría automáticamente porque el campo DateType de DataColumn estaba establecido en local. Asegúrese de verificar cuál es el DateType si está presionando DataSets.
Si no desea que cambie, configúrelo como No especificado
fuente
Me encontré con esta pregunta porque tenía un problema con las fechas UTC en las que regresa a través de la API de Twitter (campo created_at en un estado); Necesito convertirlos a DateTime. Ninguna de las respuestas / ejemplos de código en las respuestas en esta página fueron suficientes para evitar que recibiera un error "La cadena no se reconoció como una fecha y hora válida" (pero es lo más cercano que he encontrado para encontrar la respuesta correcta en SO)
Publicar este enlace aquí en caso de que esto ayude a alguien más: la respuesta que necesitaba se encontró en esta publicación de blog: http://www.wduffy.co.uk/blog/parsing-dates-when-aspnets-datetimeparse-doesnt-work/ - básicamente use DateTime.ParseExact con una cadena de formato en lugar de DateTime.Parse
fuente