MDA dateTimeInvalidLocalFormat
Observação
Este artigo é específico para aplicativos .NET Framework. Ele não se aplica a implementações mais recentes do .NET, incluindo o .NET 6 e versões posteriores.
O MDA dateTimeInvalidLocalFormat
é ativado quando uma instância DateTime que é armazenada como um UTC (Horário Coordenado Universal) é formatada com um formato que se destina a ser usado apenas em instâncias DateTime locais. Esse MDA não é ativado em instâncias DateTime não especificadas ou padrão.
Sintoma
Um aplicativo está serializando uma instância DateTime UTC manualmente usando um formato de local:
DateTime myDateTime = DateTime.UtcNow;
Serialize(myDateTime.ToString("yyyy-MM-dd'T'HH:mm:ss.fffffffzzz"));
Causa
O formato “z” do método DateTime.ToString inclui o deslocamento de fuso horário local, por exemplo, “+10h” para a hora de Sydney. Assim, ele só produzirá um resultado significativo se o valor da DateTime for local. Se o valor for a hora UTC, DateTime.ToString incluirá o deslocamento de fuso horário local, mas não exibirá nem ajustará o especificador de fuso horário.
Resolução
As instâncias DateTime UTC devem ser formatadas de modo que indiquem que são UTC. O formato recomendado para horas UTC é usar um “z” para indicar a hora UTC:
DateTime myDateTime = DateTime.UtcNow;
Serialize(myDateTime.ToString("yyyy-MM-dd'T'HH:mm:ss.fffffffZ"));
Também há um formato “o” que serializa uma DateTime, fazendo uso da propriedade Kind que serializa corretamente, independentemente se a instância é local, UTC ou não especificada:
DateTime myDateTime = DateTime.UtcNow;
Serialize(myDateTime.ToString("o"));
Efeito sobre o runtime
Esse MDA não afeta o runtime.
Saída
Não há nenhuma saída especial como resultado da ativação desse MDA. No entanto, a pilha de chamadas pode ser usada para determinar o local da chamada ToString que ativou o MDA.
Configuração
<mdaConfig>
<assistants>
<dateTimeInvalidLocalFormat />
</assistants>
</mdaConfig>
Exemplo
Considere um aplicativo que está serializando o valor DateTime UTC indiretamente usando a classe XmlConvert ou DataSet, conforme mostrado a seguir.
DateTime myDateTime = DateTime.UtcNow;
String serialized = XMLConvert.ToString(myDateTime);
As serializações XmlConvert e DataSet usam formatos locais para a serialização, por padrão. Opções adicionais são necessárias para serializar outros tipos de valores DateTime, como UTC.
Para esse exemplo específico, passe XmlDateTimeSerializationMode.RoundtripKind
para a chamada ToString
em XmlConvert
. Isso serializa os dados como uma hora UTC.
Se estiver usando um DataSet, defina a propriedade DateTimeMode no objeto DataColumn como Utc.
DateTime myDateTime = DateTime.UtcNow;
String serialized = XmlConvert.ToString(myDateTime,
XmlDateTimeSerializationMode.RoundtripKind);