MDA de dateTimeInvalidLocalFormat
Nota:
Este artículo es específico de .NET Framework. No se aplica a implementaciones más recientes de .NET, incluidas .NET 6 y versiones posteriores.
El MDA dateTimeInvalidLocalFormat
se activa cuando una instancia de DateTime que está almacenada como horario universal coordinado (UTC) tiene un formato pensado para usarse solo para instancias locales de DateTime. Este MDA no está activado para instancias de DateTime sin especificar o predeterminadas.
Síntoma
Una aplicación está serializando manualmente una instancia de DateTime UTC mediante un formato local:
DateTime myDateTime = DateTime.UtcNow;
Serialize(myDateTime.ToString("yyyy-MM-dd'T'HH:mm:ss.fffffffzzz"));
Causa
El formato "z" para el método DateTime.ToString incluye el desplazamiento de zona horaria local, por ejemplo, "+ 10:00" para la hora de Sydney. Por lo tanto, solo genera un resultado significativo si el valor de DateTime es local. Si el valor es la hora UTC, DateTime.ToString incluye el desplazamiento de zona horaria local, pero no muestra ni ajusta el especificador de zona horaria.
Solución
Las instancias de DateTime UTC deben tener el formato de una manera que indique que son UTC. El formato recomendado para la hora UTC es usar un carácter "Z" para indicar la hora UTC:
DateTime myDateTime = DateTime.UtcNow;
Serialize(myDateTime.ToString("yyyy-MM-dd'T'HH:mm:ss.fffffffZ"));
También hay un formato "o" que serializa un instancia de DateTime mediante la propiedad Kind, que serializa correctamente independientemente de si la instancia es local, UTC o sin especificar:
DateTime myDateTime = DateTime.UtcNow;
Serialize(myDateTime.ToString("o"));
Efecto en el Runtime
Este MDA no afecta al tiempo de ejecución.
Output
No hay ningún resultado especial como consecuencia de la activación de este MDA, aunque se puede usar la pila de llamadas para determinar la ubicación de la llamada a ToString que ha activado el MDA.
Configuración
<mdaConfig>
<assistants>
<dateTimeInvalidLocalFormat />
</assistants>
</mdaConfig>
Ejemplo
Imagine una aplicación que está serializando indirectamente un valor DateTime UTC mediante la clase XmlConvert o DataSet de la siguiente manera.
DateTime myDateTime = DateTime.UtcNow;
String serialized = XMLConvert.ToString(myDateTime);
Las serializaciones XmlConvert y DataSet usan formatos locales para la serialización de forma predeterminada. Se necesitan opciones adicionales para serializar otros tipos de valores DateTime, como UTC.
Para obtener este ejemplo concreto, pase XmlDateTimeSerializationMode.RoundtripKind
a la llamada a ToString
en XmlConvert
. Con esto se serializan los datos como una hora UTC.
Si usa DataSet, establezca la propiedad DateTimeMode del objeto DataColumn en Utc.
DateTime myDateTime = DateTime.UtcNow;
String serialized = XmlConvert.ToString(myDateTime,
XmlDateTimeSerializationMode.RoundtripKind);