sexta-feira, 15 de janeiro de 2010

Problemas com datas em javascript

 

A tempos atrás, construí um WebControl de entrada de data, com calendário vinculado estilo redoma. Toda a montagem do calendário é feito via javascript, com vários cálculos com datas.

Acontece que fazer operações com objetos Date() no javascript envolve fazer contas em milisegundos. Então, se você quisesse fazer um cálculo para pegar o próximo dia a partir de uma data, a maneira sugerida é usar

var objData = new Date();

objData.setMilliseconds(objData.getMilliseconds()  +  86400000);

Onde 86400000 = total de milisegundos de um dia.

Daí, o mais natural, para mim, foi fazer 2 prototypes de métodos, para extender o objeto Date:

Date.prototype.addMilliseconds = function(value) { 
                                                                     
this.setMilliseconds(this.getMilliseconds() + value); 
                                                                    
return this; };

Date.prototype.addDays = function(value) {
                                                                   
this.addMilliseconds((value * 86400000));
                                                                   
return this;}

Pensando que isto havia resolvido o meu problema, me deparei com erros na renderização de dias em outubro e fevereiro. Analisando o problema, vi que em 2 datas em específico (17/Outubro e 20/Fevereiro), a soma de 1 dia retornava 17/10/2009 23:00 ao invés do dia 18, e o mesmo ocorria em fevereiro.

Verificando a documentação, constatei que o objeto Date() é vinculado a configuração de ajuste automático de horário de verão do sistema operacional. E que, quando este parâmetro estava desligado, o cálculo funcionava corretamente.

Como meu cálculo não faz nenhum tratamento com a parte de horário da data, o que fiz foi acrescentar uma condição ao addDays:

Date.prototype.addDays = function(value) {var dia = this.getDate();
                                                                                 var mes = this.getMonth();
                                                                                  var ano = this.getFullYear();
                                                                                  this.addMilliseconds((value * 86400000));   

                                                                               if (dia == this.getDate() &&
                                                                                    mes == this.getMonth() &&
                                                                                   ano == this.getFullYear()) 
                                                                                                this.addMilliseconds((3600000 * 2));
                                                                              return this;}

Ou seja, caso o meu cálculo de próximo dia retornou o mesmo dia, mês e ano originais, somo 2 horas ao período, retornando uma data correta.

Nenhum comentário:

Postar um comentário