O JavaScript tem um objeto embutido, Date, que armazena data e hora e fornece métodos para gerenciá-las.
Ele foi baseado na classe java.util.Date do Java, que foi substituída no início da década de 2010, mas, por compatibilidade retroativa, o Date do JavaScript continua por aí.
Como é difícil lidar com datas em geral e como o tratamento de fuso horário é ruim ou simplesmente inexistente, existem muitas bibliotecas, como moment.js, day.js, date-fns e luxon.
Nenhuma delas está disponível no Exercism.
Nos seus próprios projetos, não use um pacote obsoleto ou sem manutenção como o moment.js; prefira alternativas mais modernas, como o luxon, ou o Temporal, que ainda não está amplamente disponível.
Este exercício foca no Date, que continuará relevante até o fim do JavaScript.
Um objeto Date é uma instância da classe Date.
Ele pode ser criado sem passar nenhum argumento à função construtora.
Isso resulta em um objeto Date que representa a data e a hora atuais:
const now = new Date();
// => Thu Apr 14 2022 11:46:08 GMT+0530 (India Standard Time)
// Shows current day, date and time (in your time zone).
Se um número for passado, ele será interpretado como um timestamp.
Um timestamp é um número inteiro que representa a quantidade de milissegundos decorridos desde 1º de janeiro de 1970 UTC+0.
const epoch = new Date(0);
// Thu Jan 01 1970 01:00:00 GMT+0100 (Central European Standard Time)
const another = new Date(1749508766627);
// Tue Jun 10 2025 00:39:26 GMT+0200 (Central European Summer Time)
É de se esperar que new Date(0) gere o objeto de data "mais antigo", mas o JavaScript converte a data para o seu fuso horário local, o que significa que só quem está em um fuso GMT / UTC+0 é que vai obter de fato o valor da época Unix.
Você pode passar ao construtor Date um valor de string que representa uma data.
O único formato consistente entre implementações é a versão simplificada das chamadas strings de timestamp ISO 8601, reconhecidas e padronizadas internacionalmente.
Um instante no tempo em UTC se parece com isto:
YYYY-MM-DDTHH:mm:ss.mssZ
YYYYMMDDTHHmmss.mssZ
Onde ocorrem as seguintes substituições:
| Chave | Descrição | Padrão |
|---|---|---|
| YYYY | O ano civil, representado com 4 dígitos | |
| MM | O mês civil, representado com 2 dígitos | 01 |
| DD | O dia civil, representado com 2 dígitos | 01 |
| T | Uma letra T literal, que separa a data da hora | |
| HH | As horas em relógio de 24 horas, 2 dígitos | 00 |
| mm | Os minutos, 2 dígitos | 00 |
| ss | Os segundos, 2 dígitos | 00 |
| mss | Os milissegundos, 3 dígitos | 000 |
| Z | Uma letra Z literal, ou um deslocamento +/-HH:mm
|
A letra Z literal indica UTC (sem fuso horário, sem horário de verão).
Como a maioria dos componentes tem valores padrão, é válido omitir partes no final:
YYYY-MM-DD
O padrão é o horário 00:00:00.000
Se o timestamp não terminar em Z e não terminar em +HH:mm ou -HH:mm (que indicam um deslocamento de fuso horário), por razões históricas aplica-se o seguinte:
Quando o deslocamento de fuso horário está ausente, formas apenas com data são interpretadas como horário UTC, e formas com data e hora são interpretadas como horário local. A interpretação como horário UTC se deve a um erro histórico na especificação, que não era compatível com a ISO 8601, mas que não pôde ser corrigido por causa da compatibilidade com a web. Veja Broken Parser – A Web Reality Issue.
Outros formatos aceitos por Date.parse podem ou não funcionar.
Ao trabalhar com datas em JavaScript, use sempre um timestamp ISO 8601 ao converter de string para Date.
Formas apenas com data são permitidas, mas nem todos os formatos ISO 8601 são compatíveis. Consulte a página que explica a versão simplificada no MDN.
Um objeto de data existente também pode ser usado como argumento do construtor.
Isso cria uma cópia do objeto Date existente, com a mesma data e a mesma hora.
const t1 = new Date();
const t2 = new Date(t1);
// Values of t1 and t2 will be the same.
Uma data que representa apenas uma data pode ser criada passando três números. Uma data que representa data e hora pode ser criada passando 6 números.
const date1 = new Date(95, 11, 17);
// Creates Date for Dec 17 1995 00:00 if your local timezone is equivalent to UTC.
const date2 = new Date(2013, 12, 5, 13, 24, 0);
// Creates Date for Jan 5 2014 13:24 if your local timezone is equivalent to UTC.
O segundo valor é o month, que começa em 0 para janeiro e vai até 11 para dezembro.
Date.parse()Você pode encontrar menções ou referências a uma função de análise de datas, Date.parse.
Como essa função tem poucas invariantes (verdades) e o restante da implementação não é especificado (e, portanto, não é padrão), não convém usá-la.
Date
Há vários métodos em objetos de data que retornam os componentes da data:
getFullYear(); // Get the year (4 digits)
getMonth(); // Get the month, from 0 to 11.
getDate(); // Get the day of month, from 1 to 31.
getHours(); // Get the hour in a 24 clock, from 0 to 23
getMinutes(); // Get the minutes, from 0 to 59
getSeconds(); // Get the seconds, from 0 to 59
getMilliseconds(); // Get the milliseconds, from 0 and 999
getDay(); // Get the day of week, from 0 (Sunday) to 6 (Saturday).
Cada um deles tem uma variante set correspondente (por exemplo, setFullYear) para atualizar o valor.
Qualquer valor que ultrapasse o limite passa para o componente seguinte:
const date = new Date('2025-02-28T12:42:00Z');
// => Fri Feb 28 2025 13:42:00 GMT+0100 (Central European Standard Time)
date.setDate(29);
// there was no February 29th in 2025.
date.getDate();
// => 1
date.toString();
// => Sat Mar 01 2025 13:42:00 GMT+0100 (Central European Standard Time)
Existem variantes UTC de todos os métodos, que desconsideram o fuso horário local.
Objetos de data têm um método getTime() que retorna o timestamp UNIX em milissegundos, ou seja, a quantidade de milissegundos desde a meia-noite do início de 1º de janeiro de 1970, UTC.
Além disso, o método toISOString() está disponível para converter um objeto de data em uma string de timestamp ISO 8601.
Os operadores maior que (>) e maior ou igual (>=), assim como menor que (<) e menor ou igual (<=), podem ser usados diretamente entre duas datas ou entre uma data e um número.
Isso funciona porque o JavaScript tenta converter a data em um primitivo.
Ao fazer uma comparação entre duas datas, ou entre uma data e um número, o JavaScript chama [Symbol.toPrimitive]("number"), que internamente chama date.valueOf().
Esta última é a mesma coisa que chamar date.getTime().
Se você não quiser depender desse comportamento, converta para número usando getTime() primeiro.
Datas não podem ser comparadas com igualdade (== e ===), mas o resultado de .getTime() pode.
Neste exercício, você vai trabalhar com algumas funções para gerenciar compromissos. O sistema guarda tudo em strings formatadas conforme a ISO 8601, mas não é assim que as pessoas usam o calendário. Várias funções são necessárias para converter entre os diversos formatos.
Crie um compromisso daqui a n dias, no horário atual.
A função recebe n dias e retorna o horário do compromisso daqui a n dias.
createAppointment(4, now);
// Given now is Sun Oct 05 2022 23:28:43 GMT+0600 (Bangladesh Standard Time)
// => Sun Oct 09 2022 23:28:43 GMT+0600 (Bangladesh Standard Time)
Se o segundo parâmetro now não for usado, o horário atual deve ser usado em vez dele.
Várias ferramentas só funcionam com o formato ISO 8601, padronizado internacionalmente.
Escreva a função getAppointmentTimestamp para receber uma data e retornar uma string nesse formato.
const appointment = new Date(Date.UTC(2010, 6, 16, 12, 42, 0, 0));
getAppointmentTimestamp(appointment);
// => '2010-07-16T12:42:00.000Z'
Timestamps são difíceis de ler; uma função para obter os detalhes do compromisso deve ajudar com isso.
A função getAppointmentDetails recebe um timestamp no formato ISO 8601 e retorna o ano, o mês, o dia, a hora e o minuto.
getAppointmentDetails('2022-04-24T08:15:00.000');
// => { year: 2022, month: 3, date: 24, hour: 8, minute: 15 }
A função receberá como primeiro argumento o horário do compromisso e como segundo argumento um objeto com algumas opções. Você deve atualizar o compromisso de acordo com as opções no objeto e retornar a nova data do compromisso. O objeto de opções pode ter várias opções.
updateAppointment('2022-02-09T09:20:00.000', { month: 6 });
// => { year: 2022, month: 6, date: 9, hour: 10, minute: 20 }
A função receberá dois compromissos (timestamps) como argumentos. Você deve retornar a diferença entre esses dois horários em segundos.
Como meio segundo é quase insignificante, arredonde o número antes de retorná-lo.
timeBetween('2022-12-12T09:20:00.000', '2022-12-18T08:30:00.000');
// => 515400
Por fim, quando o compromisso é marcado, o sistema precisa verificar se ele é válido. Em outras palavras, o compromisso deve estar no futuro, e não no passado.
Escreva a função isValid, que recebe dois argumentos, um timestamp de compromisso (string) e o horário atual como timestamp (string), e retorna true se o compromisso estiver no futuro, dado o horário atual.
isValid('2022-02-11T23:00:00.000', '2022-02-08T23:00:00.000');
// => true
Crie sua conta no Exercism para aprender e dominar JavaScript com 37 conceitos159 exercícios e mentoria humana de verdade, tudo de graça.