DateTime, Serialização de DataSets em WCF, Horário de Verão... uma combinação com muitas surpresas!
Leonel Fraga de Oliveira 17/08/2011 22:48

Veja a seguinte situação: Você possui um serviço WCF que está hospedado em um servidor e vários clientes que acessam este serviço. Este serviço possui um método que retorna um DataSet, serializando-o através do WCF e a classe cliente exibe o resultado em tela.

Pois bem, você possui neste DataSet uma (ou mais) tabela com um campo DateTime, e no seu banco de dados está gravado o valor, por exemplo, 17/10/2011 08:00, mas a sua aplicação exibe o valor 17/10/2011 09:00.

O que!!! Quer dizer que a aplicação está exibindo este valor uma hora ADIANTADA? Exatamente isso, meu querido! Se fomos extrair este campo para uma variável DateTime e verificarmos o resultado do método IsDayLightSavingTime(), o mesmo retornará True, indicando que a data em questão cai no horário de verão.

Se fomos olhar isso mais a fundo na aplicação cliente, veremos que o valor já considerando o horário de verão (no nosso caso, 1 hora adiantada) já vem do próprio DataSet que recuperamos via WCF do servidor. Se a aplicação cliente extraísse esse valor diretamente do banco de dados ele seria exibido corretamente. E se quisermos exibir o valor do banco de dados, como faz?

Na máquina que executa a aplicação cliente, caso você esteja utilizando o Windows XP, dê um duplo clique no relógio, acesse a guia “Fuso Horário” e desmarque a opção “Ajustar automaticamente para o horário de verão” e o seu problema estará resolvido e a aplicação passará a exibir as horas conforme estão gravadas no banco de dados.

Maaaaaaaas... tem um pequeno grande porém nesta “solução”: E se este flag do horário de verão não puder ser desabilitado pelo usuário (permissões no sistema, entre outros) e não acho um meio na aplicação cliente de fazer as horas serem exibidas corretamente, sento e choro?

Sentar e chorar é uma hipótese dependendo de como você modelou a parte servidora do seu sistema. Mas a solução definitiva é a seguinte: Ao obter um DataSet do banco de dados, devemos modificar uma propriedade chamada DateTimeMode das colunas DateTime das tabelas deste DataSet para DataSetDateTime.Unespecified, que informa para o WCF não recalcular as datas para a zona de horário das aplicações clientes na hora da serialização.

Vamos ao código!

public DataSet RetornaDataSet()
{
	DataSet ds = new DataSet();
	//Preencher o DataSet com os valores do banco de dados aqui

	//Agora, iremos modidicar as colunas DateTime das tabelas para ignorarem o recálculo de data/hora no momento da serialização WCF
	foreach (DataTable tabela in ds.Tables)
	{
		foreach (DataColumn coluna in tabela.Columns)
		{
			if ((coluna.DataType == typeof(DateTime)) || (coluna.DataType == typeof(DateTime?)))
			{
				coluna.DateTimeMode = DataSetDateTime.Unspecified;
			}
		}
	}
	return ds;
}

Com este código modificamos todas as colunas com o tipo DateTime para que quando o DataSet for serializado via WCF, as datas não sejam recalculadas conforme a zona de tempo do usuário cliente (horário de verão, fuso-horáro, etc.).

É isso aí!

Leonel Fraga de Oliveira Leonel Fraga de Oliveira é formado em Processamento de Dados na Faculdade de Tecnologia de São Paulo (FATEC-SP - 2002) e anteriormente em Técnico em Eletrônica, pela ETE Professor Aprígio Gonzaga (lá em 1999).
Atualmente trabalha como Analista de Sistemas na Prefeitura Municipal de São Caetano do Sul - SP
Tem como hobbies DJing (também trabalha como DJ freelancer) e ciclismo, além da manutenção dos sites NeoMatrix Light e NeoMatrix Tech.
Gosta de música eletrônica, tecnologia, cinema (super fã de Jornada nas Estrelas), gastronomia e outras coisas mais.


Compartilhe nas redes sociais

   

Deixe seu comentário

comments powered by Disqus