JavaScript, objeto Date e o horário de verão

by SrECosta outubro 13, 2007 12:32

Olá.

     Semana passada lidei com um problema relacionado com JavaScript, o objeto Date(), ASP.NET RangeValidators e o horário de verão.

Cenário do problema

     Meu projeto atual envolve implementar melhorias e correções em uma aplicação web ASP.NET 1.1. Uma destas correções referia-se a um problema de validação no qual o usuário digitava uma data de nascimento, por exemplo, 04/11/1973 ou 06/11/1988, portanto, datas válidas, e o sistema a consistia informando que era inválida.

     A validação do campo é bem típica, padrão das aplicações ASP.NET 1.1, utiliza um controle ASP.NET RangeValidator configurado para validar um intervalo de datas. A propriedade MinimumValue está configurada como 01/01/1753 e a propriedade MaximumValue está configurada como DateTime.Now.ToString("dd/MM/yyyy"), ou seja, qualquer data válida que o usuário digitasse entre janeiro de 1753 e hoje, deveria ser considerada válida e dentro do intervalo.

     Entretanto, especifica e somente para as duas datas que informei acima, o controle RangeValidator retornava falso e impedia a finalização do formulário. Qualquer outra data informada era considerada válida. Tanto era que mesmo a aplicação tendo sido escrita em 2003 somente neste período récem este problema foi relatado.

Causa do problema

     Os controles de validação do ASP.NET 1.1 referenciam um arquivo JavaScript chamado WebUiValidation.js. Este arquivo é instalado com o ASP.NET e é copiado para o diretório \Inetpub\Wwwroot\aspnet_client\system_web\1_1_4322 quando o ASP.NET é registrado no IIS.  Este arquivo contém as implementações client-side de várias funcionalidades do ASP.NET e, entre elas, uma função chamada ValidatorConvert.

     A função ValidatorConvert é a responsável por indicar se um valor informado para um campo protegido por um controle RangeValidator, independente do tipo, está dentro do intervalo determinado. Durante meu debug dessa função descobri que o problema estava nela mas era causado por um "estranho" comportamento do objeto Date() do JavaScript. Veja só:

     Imagine que você crie um objeto Date() em JavaScript para a data 04/11/1973. Mais ou menos assim:
     var date = new Date(1973, 10, 04); 
     /* Lembrando que em JavaScript, os meses são considerados de 0 a 11, ou seja, 0 = Janeiro, 1 = Fevereiro, ..., 10 = Novembro, 11 = Dezembro. */

     Seria de se esperar que o objeto date récem-criado estivesse configurado para ano 1973, mês novembro e dia 04, certo? Nem tanto. Curiosamente o objeto date respondia por ano = 1973, mês 10 e dia 3. Por causa disto, por causa de o objeto Date() do JavaScript estar retrocedendo um dia, a função ValidatorConvert falhava e o controle RangeValidator em seguida. O mesmo comportamento ocorria para a data 06/11/1988. Mas não para nenhum outra testada.

     Qual o motivo de o construtor do objeto Date() do JavaScript se comportar desta forma para estas datas? Horário de verão. Segundo a documentação em http://support.microsoft.com/kb/931836/en-us, o horário de verão em Brasília, com GMT -03:00, começa no primeiro domingo de novembro e termina no último domingo de fevereiro. Isto é pré-configurado no sistema operacional e, embora esteja incorreto (já que nosso horário de verão obedece a motivos políticos e esse ano, por exemplo, vai começar no segundo domingo de outubro), é o responsável por este comportamento do objeto Date() do JavaScript.

     Ok, isto é um comportamento padrão do JavaScript em resposta às configurações do horário de verão. Mas, e se minha aplicação não precisar tomar conhecimento disto? E se este comportamento for indesejado? 

Resolução do problema

     Bem, a resolução do problema é simples e implica em criar um objeto Date() em JavaScript fornecendo ao construtor os parâmetros ano, mês, dia, hora, minuto e segundo, sendo que hora, minuto e segundo podem ser informados como 1. Assim:
     var date = new Date(1973, 10, 04, 1, 1, 1);
     if (year < 100) {
                 date.setFullYear(year);
     }

     Entretanto, uma vez que este erro ocorre dentro do arquivo WebUiValidation.JS do ASP.NET, como implementar esta solução fornece duas alternativas: 

     1. Eu poderia substituir o controle RangeValidator na minha aplicação por um controle CustomValidator e implementar a validação da intervalo de datas na mão. A vantagem está em não precisar modificar o arquivo WebUiValidation.JS. A desvantagem está em ter trinta páginas .ASPX que utilizam esse controle. Mudá-las, uma a uma, pode não ser convidativo.

     2. Ou modificar o arquivo WebUiValidation.JS, especificamente a função ValidatorConvert, na qual o problema com o objeto Date() ocorreu. A vantagem está em que eu não teria de modificar todas as 30 páginas .ASPX que utilizam o controle RangeValidator e, melhor dos mundos, não teria de trocar um validator pelo outro. A desvantagem está em sair atualizando o arquivo WebUiValidation.JS em todos os servidores da cadeia de desenvolvimento: minha máquina, testes, homologação, produção e por aí vai.

     Se você passar por este problema pode escolher entre as duas saídas acima. Eu utilizei a segunda.

Horário de Verão Brasileiro

     Aproveitando o post, vale lembrar que a MS liberou um site com recursos, dicas de ajustes e configurações para o horário de verão brasileiro a iniciar em 14/10/2007. Visite.

     Agradeço ao Benson Yu que me ajudou com este problema no fórum de ASP.NET. Veja a thread original em http://forums.asp.net/t/1165489.aspx.

Eduardo.

5.0 ponto(s). Avaliado por 2 pessoas

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags: , , ,

Desenvolvimento e Codificação

Comentários

Os comentários estão fechados

Powered by BlogEngine.NET 1.4.5.0
Theme by Mads Kristensen | Modified by Mooglegiant

Eduardo Costa

Desenvolvedor de software, empreendedor, marido e criador de quatro gatos em São Paulo, SP.
Sobre o Mutamblog.

Anúncios