domingo, 21 de setembro de 2008

JavaScript Tutorial: O Objeto Date (Parte 1)

Quando criamos nosso sistema de informações, é apenas uma questão de tempo até precisarmos manipular, medir, alterar, calcular e comparar datas e horas. Quando nosso sistema é (como a grande maioria!) baseado em web, então grande parte desta etapa é feita no próprio navegador do cliente, via javascript, o que é muito bom, pois aumenta a produtividade, envitando posts desnecessários e diminuindo a carga sobre o servidor.
Interessante que tenho visto pessoas com dificuldade neste assunto, e nem sempre se acha um bom tutorial em português para ajudar. Assim, O Pajé ficou motivado a escrever este artigo, contendo todas as ferramentas básicas para aprender e utilizar o objeto Date do JavaScript sem medo. Como pretendo um tutorial abrangente, dividi-o em duas partes (em breve sairá do forninho a segunda!!).
Bom, vamos do começo: o objeto Date é o objeto responsável, no javascript, por lidar com informações de tempo, desde o ano atual até o último milisegundo, passando pelo dia da semana, mês, hora, minuto, etc. Se seu sistema contiver campos como Período, Data Inicial, Horário, Duração, Diurno, Noturno, Calendário, etc., então freqüentemente você precisará do objeto Date entrando em ação! E não se engane: estes campos são dos mais corriqueiros!!
Manipular as datas no javascript é bom porque evita que o usuário envie para o servidor informações que certamente não vão passar pela validação e vão ter que retornar ao mesmo ponto. Com Date, você pode validar se a data informada está correta, se o período compreende ao menos um valor mínimo, e se a data final é maior que a inicial, por exemplo.
Claro que, no servidor, você deverá revalidar tudo (não seja bobo!! Tem clientes tentando passar a perna também!!), mas, tendo uma validação prévia no cliente, então as chances da validação falhar no servidor e se retornar ao mesmo ponto são menores. Acredite: este tipo de artifício ajuda muito a desafogar seu servidor!!
Então vamos ao que interessa!! Antes de utilizar o objeto, é preciso criá-lo:

var data = new Date();

Isto cria um objeto Date válido, contendo a data e instante atual (do momento da criação). Mesmo que a data desejada seja outra, para começar é preciso instanciar assim.
Abaixo, as funções mais importantes do objeto Date e suas descrições:

var data = new Date();
// Número de millisegundos desde 01/01/1970 @ 00:00
data.getTime();
// Número de segundos (0-59)
data.getSeconds();
// Número de miutos (0-59)
data.getMinutes();
// Número da hora (0-23)
data.getHours();
// Número do dia da semana, sendo 0=domingo e 6=sábado
data.getDay();
// Dia do mês (0-31)
data.getDate();
// Número do mês. CUIDADO: 0=janeiro, e 11=dezembro.
// Muita gente erra achando que janeiro é mês 1!!
data.getMonth();
// Número do ano, com 4 dígitos
data.getFullYear();

Apenas com estes comandos já dá para resolver grande parte dos problemas. Lembre-se de que o objeto date suporta comparações com os operadores ">", "<", ">=", "<=", "+", "-" e que é sempre seguro, quando necessário, convertê-lo para inteiro com a função getTime(). Com estes operadores, podemos somar ou diminuir uma data da outra (importante para cálculo de períodos!!), podemos comparar qual data é maior e qual é menor (importante em validações), etc. Uma referência completa, embora exaustiva, sobre o objeto Date de javascript encontra-se aqui.


  • Definindo uma data específica
Claro que o "var data = new Date()" nem sempre é o que a gente quer. Muitas vezes, queremos que o objeto criado represente uma data específica, seja ela lida de um campo da tela, seja ela calculada de alguma forma. Assim, podemos utilizar outros construtores do objeto Date, conforme mostrado a seguir:

var hoje = new Date();
var anoQueVem = new Date('January 1, '+(hoje.getFullYear()+1));
var diasRestantes = anoQueVem - hoje;

Este construtor recebe uma String com o nome do mês, dia e ano. No código acima, também usamos os operadores para saber quanto tempo resta até o fim do ano. Assim, posso calcular os dias, minutos, segundos e milisegundos para o reveillón!! Se você tem um portal que espera um grande lançamento, é isto que você deve usar!!
Outra maneira de inserir uma data, utilizando apenas valores numéricos, é esta:

var dataNova = new Date(ano, mes, dia[, hora[, minuto[, segundo[,milisegundo]]]]);

Assim é possível se criar um objeto Date com o valor de qualquer data, até a precisão dos milisengundos. Lembre-se de que o valor do mês parece sempre diminuído de 1, porque janeiro=0, fevereiro=1, março=2, ..., dezembro=11!! Até o argumento "dia" é obrigatório, os outros são opcionais. Exemplos:

//Dia de natal: 25/12/2008.
var data1 = new Date(2008, 11, 25);

//Independência: 07/09/2001.
var data2 = new Date(2001, 8, 7);

//Meu almoço, no aniversário do Rio de Janeiro.
var data3 = new Date("March 20, 2008 12:20:00 pm");
var data4 = new Date(2008, 2, 20, 12, 20, 00);


Observe que data3 e data4 são iguais.

Ocorre menos assiduamente, mas, caso você tenha um número inteiro (geralmente advindo do em data.getTime()) e quer convertê-lo para uma data, basta usar a função estática Date.parse, ou o construtor que recebe um único inteiro:

var data1 = new Date(inteiro); //inteiro = número inteiro
var data2 = Date.parse(inteiro); //inteiro = número inteiro

É isso, gente!! Na segunda parte do tutorial, vamos fazer um aplicativo para mostrar a data e hora, e vamos construir um lindo relógio digital para seu portal!! Qualquer coisa (gostou, não gostou, ajudou, foi inútil, etc. e tal...), comentem!! É só clicar aí embaixo!!

Veja a continuação na segunda parte!!

6 comentários:

Anônimo disse...

Muito bom esse teu tutorial de como manipular datas em javascript, me ajudou muitoooo.

Valeu, e continue compartilhando conhecimento.

O Pajé disse...

Beleza, camarada!! Fico feliz de ter sido útil!! Obrigado pelo retorno!!
Continue visitando o Pajé!! Aqui tem sempre novidades e tutoriais interessantes!!

Anônimo disse...

Mandou bem paje estou tentando diminuir uma data de outra sendo q ano, mes e dia somente q contam tem uma funçao pra isso ??

O Pajé disse...

Muito obrigado, rapaz.

Certamente que tem o que você precisa, embora eu não tenha entendido muito bem com a sua descrição. Normalmente, para diminuir uma data de outra, você tem um caminho bem simples:

1- Crie um objeto Date com a data inicial;
2- Diminua os dias, horas, minutos e etc. através da transformação destes valores em milissegundos;
3- Formate o objeto Date.

Exemplo:

Um objeto Date da data de hoje:

var dataInicial = new Date();

Diminuindo 1 dia e 2 horas (ou seja, 26 horas):

var fator = 26 * 60 * 60 * 1000;
// cara hora tem 60 minutos, que tem 60 segundos, que tem 1000 milissegundos.

dataInicial.setTime(dataInicial.getTime() - fator);

OBS: certifique-se de que esta subtração não vai dar um número menor do que zero, de outra forma, não vai funcionar, pois não pode existir uma data negativa!!

Anônimo disse...

Olá Pagé, valeu pelas dicas, porém assim, tem como eu instanciar um objeto Date() passando por parâmetro uma data no formato do banco, como o mysql, exemplo: var data = new Date('2012-07-12');
Isso se torna um objeto válido? Obrigado.

O Pajé disse...

Olá Amigo,

Sim, você pode fazer isto. Mas atente para que você está passando uma data formatada, e isto pode ser algumas vezes perigoso, pois força que o Javascript assuma alguns parâmetros.

1- Primeiramente, o navegador vai assumir que você está usando a máscara de formatação yyyy-mm-dd, o que não é o padrão em todos os lugares do mundo (não o é no Brasil, por exemplo, onde mais facilmente se formataria dd/mm/yyyy).

2- O navegador pode mudar o locale de sua data. Por exemplo, pode assumir que esta data é a data do fuso horário "0". Se você mora no fuso horário GMT-0500, por exemplo (5 horas antes do meridiano de Greenwich), então seu horário para esta data poderá ser 19:00 do dia anterior, pois ela é entendida como a de Greenwich, e não a de sua localização. Isto pode gerar alguma confusão.

Fiz o seguinte código para você testar as suas datas:

var data = new Date('2012-07-12');
window.alert(data);

Troque os parâmetros e teste em vários navegadores, observando os resultados.

Espero ter ajudado!!
Abraços,
Pajé