Como desenvolvedor de software, você não pode fugir da manipulação de datas. Quase todo aplicativo que um desenvolvedor constrói terá algum componente em que a data / hora precisa ser obtida do usuário, armazenada em um banco de dados e exibida de volta ao usuário.
Pergunte a qualquer programador sobre sua experiência em lidar com datas e fusos horários e eles provavelmente compartilharão algumas histórias de guerra. Manipular campos de data e hora certamente não é uma ciência espacial, mas pode ser entediante e sujeito a erros.
Existem centenas de artigos sobre o assunto por aí, no entanto, a maioria ou é muito acadêmica, com foco em detalhes essenciais, ou é muito irregular, fornecendo pequenos trechos de código sem muitas explicações que os acompanham. Este guia detalhado para manipulação de DateTime deve ajudá-lo a entender os conceitos de programação e as melhores práticas relevantes para hora e data, sem ter que navegar por um mar de informações sobre este tópico.
Neste artigo, irei ajudá-lo a pensar com clareza sobre os campos de data e hora e sugerir algumas práticas recomendadas que podem ajudá-lo a evitar o inferno de data / hora. Aqui, exploraremos alguns dos principais conceitos necessários para manipular valores de data e hora corretamente, formatos que são convenientes para armazenar valores DateTime e transferi-los por meio de APIs e muito mais.
Para começar, a resposta certa para o código de produção é quase sempre usar uma biblioteca adequada em vez de criar a sua própria. As possíveis dificuldades com o cálculo de DateTime discutidas neste artigo são apenas a ponta do iceberg, mas ainda é útil saber sobre elas, com ou sem uma biblioteca.
Bibliotecas de datas ajudam de várias maneiras a tornar sua vida mais fácil. Eles simplificam muito a análise de datas, operações aritméticas e lógicas de datas e formatação de datas. Você pode encontrar uma biblioteca de datas confiável para o front-end e o back-end para fazer a maior parte do trabalho pesado para você.
No entanto, costumamos usar bibliotecas de datas sem pensar em como a data / hora realmente funciona. Data / hora é um conceito complexo. Os bugs que surgem devido ao seu entendimento incorreto podem ser extremamente difíceis de entender e corrigir, mesmo com a ajuda de bibliotecas de dados. Como um programador, você precisa entender os fundamentos e ser capaz de avaliar os problemas que as bibliotecas de datas resolvem para tirar o máximo proveito deles.
Além disso, as bibliotecas de data / hora só podem levá-lo até certo ponto. Todas as bibliotecas de data funcionam dando a você acesso a estruturas de dados convenientes para representar um DateTime. Se você estiver enviando e recebendo dados por meio de uma API REST, eventualmente precisará converter a data em uma string e vice-versa, porque JSON não tem uma estrutura de dados nativa para representar DateTime. Os conceitos que delineei aqui irão ajudá-lo a evitar alguns dos problemas comuns que podem surgir ao fazer essas transformações data-a-string e string-to-date.
Nota: Mesmo que eu tenha usado JavaScript como a linguagem de programação discutida neste artigo, esses são conceitos gerais que se aplicam, em grande medida, a praticamente todas as linguagens de programação e suas bibliotecas de datas. Portanto, mesmo que você nunca tenha escrito uma linha de JavaScript antes, fique à vontade para continuar lendo, pois dificilmente presumo qualquer conhecimento prévio de JavaScript no artigo.
Um DateTime é um momento muito específico. Vamos pensar sobre isso. Enquanto rabisco este artigo, o relógio do meu laptop mostra 21 de julho 13h29. É o que chamamos de “hora local”, a hora que vejo nos relógios de parede ao meu redor e no meu relógio de pulso.
Mais ou menos alguns minutos, se eu pedir a minha amiga para me encontrar em um café próximo às 15h, posso esperar encontrá-la lá mais ou menos nessa hora. Da mesma forma, não haveria nenhuma confusão se, em vez disso, eu dissesse, por exemplo, 'vamos nos encontrar em uma hora e meia'. Costumamos falar sobre o tempo dessa maneira com pessoas que moram na mesma cidade ou fuso horário.
Vamos pensar em um cenário diferente: quero dizer a um amigo que mora em Uppsala, na Suécia, que quero falar com ele às 17h. Envio a ele uma mensagem: “Ei, Anton, vamos conversar às 17h”. Eu recebo imediatamente a resposta: 'Seu tempo ou meu tempo?'
Anton me disse que mora no fuso horário da Europa Central, que é UTC + 01: 00. Eu moro na UTC + 05: 45. Isso significa que quando são 17h onde eu moro, são 17h - 05h45 = 11h15 UTC, o que se traduz em 11h15 UTC + 1h = 12h15 em Uppsala, perfeito para ambos de nós.
Além disso, esteja ciente da diferença entre o fuso horário (Horário da Europa Central) e a diferença de fuso horário (UTC + 05: 45). Os países também podem decidir alterar suas compensações de fuso horário para o horário de verão por razões políticas. Quase todos os anos há uma mudança nas regras em pelo menos um país, o que significa que qualquer código com essas regras incorporadas deve ser mantido atualizado - vale a pena considerar o que sua base de código depende para isso para cada camada de seu aplicativo.
Esse é outro bom motivo pelo qual recomendamos que apenas o front end lide com fusos horários na maioria dos casos. Quando isso não acontece, o que acontece quando as regras que seu mecanismo de banco de dados usa não correspondem às de seu front end ou back end?
Esse problema de gerenciar duas versões diferentes do tempo, em relação ao usuário e em relação a um padrão universalmente aceito, é difícil, ainda mais no mundo da programação onde a precisão é fundamental e até mesmo um segundo pode fazer uma grande diferença. A primeira etapa para resolver esses problemas é armazenar DateTime em UTC.
Padronizar o horário é maravilhoso porque eu só preciso armazenar o horário UTC e, desde que eu conheça o fuso horário do usuário, sempre posso converter para o horário dele. Por outro lado, se eu souber a hora local de um usuário e seu fuso horário, posso converter para UTC.
Mas as datas e horas podem ser especificadas em muitos formatos diferentes. Para a data, você pode escrever “30 de julho” ou “30 de julho” ou “30/07” (ou 30/7, dependendo de onde você mora). Por enquanto, você pode escrever “21:30” ou “2130”.
Cientistas de todo o mundo se reuniram para resolver este problema e decidiram por um formato para descrever o tempo que os programadores realmente gostam porque é curto e preciso. Gostamos de chamá-lo de “formato de data ISO”, que é uma versão simplificada do formato estendido ISO-8601 e tem a seguinte aparência:
Para 00:00 ou UTC, usamos “Z”, o que significa hora Zulu, outro nome para UTC.
Antes de começarmos com as práticas recomendadas, aprenderemos sobre a manipulação de datas usando JavaScript para obter uma compreensão da sintaxe e dos conceitos gerais. Embora usemos JavaScript, você pode adaptar facilmente essas informações à sua linguagem de programação favorita.
Usaremos aritmética de data para resolver problemas comuns relacionados a datas que a maioria dos desenvolvedores encontra.
Meu objetivo é deixá-lo confortável ao criar um objeto de data a partir de uma string e extrair componentes de uma. Isso é algo em que uma biblioteca de datas pode ajudá-lo, mas é sempre melhor entender como isso é feito nos bastidores.
Depois de sujar as mãos com data / hora, é mais fácil pensar sobre os problemas que enfrentamos, extrair as melhores práticas e seguir em frente. Se você quiser pular para as práticas recomendadas, fique à vontade para fazê-lo, mas eu recomendo fortemente que você pelo menos dê uma olhada na seção de aritmética de data abaixo.
As linguagens de programação contêm construções úteis para tornar nossas vidas mais fáceis. O JavaScript Date
objeto é uma dessas coisas. Ele oferece métodos convenientes para obter a data e hora atuais, armazenar uma data em uma variável, realizar aritmética de data e formatar a data com base na localidade do usuário.
Devido às diferenças entre as implementações do navegador e o manuseio incorreto do horário de verão (DST), dependendo do objeto Date para aplicativos de missão crítica não é recomendado e você provavelmente deve usar uma biblioteca DateTime como Luxon, data-fns ou dayjs . (O que quer que você use, evite o Moment.js que já foi popular - muitas vezes simplesmente chamado de moment
, conforme aparece no código - uma vez que agora está obsoleto.)
Mas, para fins educacionais, usaremos os métodos que o objeto Date () fornece para aprender como JavaScript lida com DateTime.
const currentDate = new Date();
Se você não passar nada para o construtor Date, o objeto de data retornado conterá a data e a hora atuais.
Você pode então formatá-lo para extrair apenas a parte da data da seguinte maneira:
const currentDate = new Date(); const currentDayOfMonth = currentDate.getDate(); const currentMonth = currentDate.getMonth(); // Be careful! January is 0, not 1 const currentYear = currentDate.getFullYear(); const dateString = currentDayOfMonth + '-' + (currentMonth + 1) + '-' + currentYear; // '27-11-2020'
Nota: a armadilha “Janeiro é 0” é comum, mas não universal. Vale a pena verificar a documentação de qualquer idioma (ou formato de configuração: por exemplo, cron é baseado em 1) antes de começar a usá-lo.
Se, em vez disso, você deseja obter o carimbo de hora atual, pode criar um novo objeto Date e usar o método getTime ().
const currentDate = new Date(); const timestamp = currentDate.getTime();
Em JavaScript, um registro de data e hora é o número de milissegundos que se passaram desde 1º de janeiro de 1970.
Se você não pretende apoiar A conversão de uma string em um objeto de data JavaScript é feita de maneiras diferentes. O construtor do objeto Date aceita uma ampla variedade de formatos de data: Observe que você não precisa incluir o dia da semana porque JS pode determinar o dia da semana para qualquer data. Você também pode passar o ano, mês, dia, horas, minutos e segundos como argumentos separados: Claro, você sempre pode usar o formato de data ISO: No entanto, você pode ter problemas se não fornecer o fuso horário explicitamente! Qualquer um deles dará a você 25 de julho de 2016, 00:00:00, hora local. Se você usar o formato ISO, mesmo que forneça apenas a data e não a hora e o fuso horário, ele aceitará automaticamente o fuso horário como UTC. Isso significa que: Felizmente, o JavaScript moderno tem algumas funções de internacionalização convenientes integradas ao padrão Para isso, precisaremos de dois objetos: a Se, em vez disso, quiséssemos o formato holandês (D / M / AAAA), apenas passaríamos um código de cultura diferente para o Ou uma forma mais longa do formato americano, com o nome do mês soletrado: Agora, se quisermos um formato ordinal adequado no dia do mês, ou seja, “14º” em vez de apenas “14”, isso infelizmente precisa de uma solução alternativa, porque Infelizmente, Se você precisar oferecer suporte a navegadores mais antigos como o IE antes da versão 11, a formatação de data em JavaScript é mais difícil porque não havia funções de formatação de data padrão como No PHP, por exemplo, a função Você pode usar um combinação diferente de letras precedido por Se você tiver certeza do formato que deseja usar, é melhor extrair bits individuais usando as funções JavaScript que abordamos acima e criar uma string você mesmo. Podemos obter a data no formato MM / DD / AAAA como O problema com essa solução é que ela pode dar um comprimento inconsistente às datas porque alguns meses e dias do mês têm um dígito e outros dois dígitos. Isso pode ser problemático, por exemplo, se você estiver exibindo a data em uma coluna da tabela, porque as datas não se alinham. Podemos resolver isso usando uma função “pad” que adiciona um 0 à esquerda. Agora, obtemos a data correta no formato MM / DD / AAAA usando: Se preferirmos DD-MM-AAAA, o processo é semelhante: Vamos começar e tentar imprimir a data no formato 'Mês, Data, Ano'. Precisaremos de um mapeamento de índices de meses para nomes: Algumas pessoas gostam de exibir a data como 1º de janeiro de 2013. Sem problemas, tudo o que precisamos é uma função auxiliar É fácil determinar o dia da semana a partir do objeto de data, então vamos adicionar isso em: O ponto principal aqui é que, depois de extrair os números da data, a formatação está principalmente relacionada a strings. Depois de saber como analisar uma data e formatá-la, alterar uma data de um formato para outro é apenas uma questão de combinar os dois. Por exemplo, se você tem uma data no formato 21 de julho de 2013 e deseja alterar o formato para 21-07-2013, isso pode ser feito assim: Os métodos de formatação de data que discutimos acima devem funcionar na maioria dos aplicativos, mas se você realmente deseja localizar a formatação da data, sugiro que use o … Nos dá algo como Alterar o local para 'en-US' resulta em '26 de julho de 2016'. Observe como a formatação mudou, mas as opções de exibição ainda eram as mesmas - um recurso muito útil. Conforme mostrado na seção anterior, a técnica mais recente baseada em Com Se eu quiser o mês inteiro “julho”, tudo o que faço é alterar o parâmetro do mês nas opções para “longo”. JavaScript trata de tudo para mim. Para en-US, agora recebo 26 de julho de 2016. Observação: se você quiser que o navegador use automaticamente a localidade do usuário, pode passar 'indefinido' como o primeiro parâmetro. Se você quiser mostrar a versão numérica da data e não quiser se preocupar com MM / DD / AAAA vs. DD / MM / AAAA para diferentes localidades, sugiro a seguinte solução simples: No meu computador, isso gera Isso resulta em Você também pode usar algumas outras funções relacionadas para localizar a forma como a hora e a data são exibidas: Aqui está um exemplo de adição de 20 dias a uma data de JavaScript (ou seja, descobrir a data 20 dias após uma data conhecida): O objeto de data original agora representa uma data 20 dias após 20 de julho e Para calcular os carimbos de hora relativos com uma diferença mais precisa do que dias inteiros, você pode usar Assim como tudo o mais relacionado à data, comparar datas tem suas próprias pegadinhas. Primeiro, precisamos criar objetos de data. Felizmente, = todos funcionam. Portanto, comparar 19 de julho de 2014 e 18 de julho de 2014 é tão fácil quanto: Verificar a igualdade é mais complicado, pois dois objetos de data representando a mesma data ainda são dois objetos de data diferentes e não serão iguais. Comparar strings de data é uma má ideia porque, por exemplo, “20 de julho de 2014” e “20 de julho de 2014” representam a mesma data, mas têm diferentes representações de string. O snippet abaixo ilustra o primeiro ponto: Isso produzirá Este caso particular pode ser corrigido comparando os equivalentes inteiros das datas (seus carimbos de hora) da seguinte forma: Já vi este exemplo em muitos lugares, mas não gosto porque você não cria um objeto de data a partir de outro objeto de data normalmente. Então eu acho que o exemplo é importante apenas do ponto de vista acadêmico. Além disso, isso requer que os dois objetos Date se refiram exatamente ao mesmo segundo, enquanto você pode querer apenas saber se eles se referem ao mesmo dia, hora ou minuto. Vejamos um exemplo mais prático. Você está tentando comparar se o aniversário que o usuário inseriu é o mesmo que a data de sorte que você obteve de uma API. Ambos representaram a mesma data, mas infelizmente seu usuário não receberá o milhão de dólares. Aqui está o problema: JavaScript sempre assume que o fuso horário é aquele fornecido pelo navegador, a menos que seja explicitamente especificado de outra forma. Isso significa, para mim, Não é possível alterar apenas o fuso horário de um objeto de data existente, então nosso objetivo agora é criar um novo objeto de data, mas com UTC em vez do fuso horário local. Ignoraremos o fuso horário do usuário e usaremos UTC ao criar o objeto de data. Existem duas maneiras de fazer isso: Isso também funciona se você não especificar o horário, pois o padrão será meia-noite (ou seja, 00: 00: 00Z): Lembre-se: se o construtor de data receber uma string no formato de data ISO correto de AAAA-MM-DD, ele assumirá o UTC automaticamente. Um cenário comum que você encontrará é encontrar a diferença entre duas datas. Discutimos dois casos de uso: Converta ambas as datas para o carimbo de hora UTC, encontre a diferença em milissegundos e encontre os dias equivalentes. Nota: Temos um formato não padronizado. Leia o documento da API para determinar se isso significa 12 de outubro ou 10 de dezembro. Mude para o formato ISO de acordo. Sei que existem maneiras mais concisas de escrever esse código, mas gosto de escrevê-lo dessa forma por causa da clareza absoluta da lógica. Agora que estamos confortáveis com a aritmética de data, podemos entender as melhores práticas a serem seguidas e os motivos para segui-las. Se você estiver obtendo a data e a hora do usuário, provavelmente está procurando o DateTime local. Vimos na seção aritmética de data que Para remover qualquer confusão, sempre sugiro criar uma data usando A parte legal é que você pode usar as variações que permitem omitir qualquer um dos quatro últimos parâmetros se eles forem zero; ou seja, Por exemplo, se você estiver usando um selecionador de data e hora que fornece a data 2012-10-12 e hora 12:30, você pode extrair as partes e criar um novo objeto Date da seguinte maneira: Tente evitar criar uma data a partir de uma string, a menos que esteja no formato de data ISO. Use o método Data (ano, mês, data, horas, minutos, segundos, microssegundos). Se você estiver obtendo apenas a data, a data de nascimento de um usuário, por exemplo, é melhor converter o formato para um formato de data ISO válido para eliminar qualquer informação de fuso horário que possa fazer com que a data avance ou retroceda quando convertida para UTC. Por exemplo: Caso você tenha esquecido, se você criar um Sempre armazene o DateTime em UTC. Sempre envie uma string de data ISO ou um carimbo de hora para o back end. Gerações de programadores de computador perceberam essa verdade simples depois de experiências amargas tentando mostrar a hora local correta para o usuário. Armazenar a hora local no back end é uma má ideia, é melhor deixar o navegador lidar com a conversão para a hora local no front end. Além disso, deve ficar claro que você nunca deve enviar uma string DateTime como “20 de julho de 1989 12:10” para o backend. Mesmo se você enviar o fuso horário também, estará aumentando o esforço para que outros programadores entendam suas intenções e analisem e armazenem a data corretamente. Use o “Às vezes é importante saber o fuso horário em que um evento ocorreu, e a conversão para um único fuso horário oblitera irrevogavelmente essa informação. “Se você está fazendo uma promoção de marketing e quer saber quais clientes fizeram pedidos na hora do almoço, um pedido que parece ter sido feito ao meio-dia GMT não é muito útil quando realmente foi feito durante o café da manhã em Nova York.” Se você se deparar com esse tipo de situação, seria mais sensato economizar também a hora local. Como de costume, gostaríamos de criar a data no formato ISO, mas primeiro temos que encontrar a diferença de fuso horário. O objeto Date é Para meu fuso horário +05: 45, obtenho -345, este não é apenas o sinal oposto, mas um número como -345 pode ser completamente desconcertante para um desenvolvedor de back-end. Portanto, convertemos isso para +05: 45. Agora, obtemos o restante dos valores e criamos uma string ISO válida que representa o DateTime local. Se desejar, você pode agrupar as datas UTC e locais em um objeto. Agora, no backend, se você quiser saber se o evento ocorreu antes do meio-dia, horário local, você pode analisar a data e simplesmente usar o Não usamos o Às vezes, mesmo com o fuso horário local armazenado, você desejará exibir datas em um fuso horário específico. Por exemplo, os horários dos eventos podem fazer mais sentido no fuso horário do usuário atual se eles forem virtuais, ou no fuso horário onde ocorrerão fisicamente, se não forem. Em qualquer caso, vale a pena olhar de antemão soluções estabelecidas para formatação com nomes de fusos horários explícitos. Sempre configure seus servidores e bancos de dados para usar o fuso horário UTC. (Observe que UTC e GMT são não é a mesma coisa —GMT, por exemplo, pode implicar uma mudança para BST durante o verão, enquanto UTC nunca irá.) Já vimos o quanto as conversões de fuso horário podem ser problemáticas, especialmente quando não são intencionais. Sempre enviar DateTime UTC e configurar seus servidores para estarem no fuso horário UTC pode tornar sua vida mais fácil. Seu código de back-end será muito mais simples e limpo, pois não precisa fazer nenhuma conversão de fuso horário. Os dados DateTime vindos de servidores em todo o mundo podem ser comparados e classificados sem esforço. O código no back end deve ser capaz de assumir o fuso horário do servidor como UTC (mas ainda deve ter uma verificação no local para ter certeza). Uma simples verificação de configuração evita ter que pensar e codificar para conversões sempre que um novo código DateTime é escrito. A manipulação de datas é um problema difícil. Os conceitos por trás dos exemplos práticos neste artigo se aplicam além do JavaScript e são apenas o começo quando se trata de lidar adequadamente com dados e cálculos DateTime. Além disso, cada biblioteca auxiliar virá com seu próprio conjunto de nuances. O resultado final é: Use ISO no back-end e deixe o front-end para formatar as coisas adequadamente para o usuário. Os programadores profissionais estarão cientes de algumas das nuances e (ainda mais decididamente) usarão bibliotecas DateTime bem suportadas tanto no back end quanto no front end. Funções integradas no lado do banco de dados são outra história, mas espero que este artigo forneça informações suficientes para tomar decisões mais sábias nesse contexto também.Analisando uma Data
Date.now()
const date1 = new Date('Wed, 27 July 2016 13:30:00'); const date2 = new Date('Wed, 27 July 2016 07:45:00 UTC'); const date3 = new Date('27 July 2016 13:30:00 UTC+05:45');
const date = new Date(2016, 6, 27, 13, 30, 0);
const date = new Date('2016-07-27T07:45:00Z');
const date1 = new Date('25 July 2016'); const date2 = new Date('July 25, 2016');
Formatando uma Data
new Date('25 July 2016').getTime() !== new Date('2016-07-25').getTime() new Date('2016-07-25').getTime() === new Date('2016-07-25T00:00:00Z').getTime()
namespace que torna a formatação de data uma operação simples.Intl
e um Date
, inicializado com nossas preferências de saída. Supondo que gostaríamos de usar o formato americano (M / D / AAAA), ficaria assim:Intl.DateTimeFormat
const firstValentineOfTheDecade = new Date(2020, 1, 14); // 1 for February const enUSFormatter = new Intl.DateTimeFormat('en-US'); console.log(enUSFormatter.format(firstValentineOfTheDecade)); // 2/14/2020
construtor:DateTimeFormat
const nlBEFormatter = new Intl.DateTimeFormat('nl-BE'); console.log(nlBEFormatter.format(firstValentineOfTheDecade)); // 14/2/2020
const longEnUSFormatter = new Intl.DateTimeFormat('en-US', { year: 'numeric', month: 'long', day: 'numeric', }); console.log(longEnUSFormatter.format(firstValentineOfTheDecade)); // February 14, 2020
são apenas valores válidos como desta escrita são day
ou 'numeric'
. Pedindo emprestado Versão de Flavio Copes do Código de Mathias Bynens para alavancar outra parte de '2-digit'
para isso, podemos personalizar a saída do dia do mês via Intl
:formatToParts()
const pluralRules = new Intl.PluralRules('en-US', { type: 'ordinal' }) const suffixes = { 'one': 'st', 'two': 'nd', 'few': 'rd', 'other': 'th' } const convertToOrdinal = (number) => `${number}${suffixes[pluralRules.select(number)]}` // At this point: // convertToOrdinal('1') === '1st' // convertToOrdinal('2') === '2nd' // etc. const extractValueAndCustomizeDayOfMonth = (part) => { if (part.type === 'day') { return convertToOrdinal(part.value); } return part.value; }; console.log( longEnUSFormatter.formatToParts(firstValentineOfTheDecade) .map(extractValueAndCustomizeDayOfMonth) .join('') ); // February 14th, 2020
não é compatível com o Internet Explorer (IE) até o momento em que este livro foi escrito, mas todas as outras tecnologias de desktop, celular e back-end (ou seja, Node.js) tem suporte . Para aqueles que precisam suportar o IE e absolutamente precisam de ordinais, a nota abaixo (ou melhor, uma biblioteca de datas adequada) fornece uma resposta.formatToParts
em Python ou PHP.strftime
dá a você strftime('Today is %b %d %Y %X', mktime(5,10,0,12,30,99))
.Today is Dec 30 1999 05:10:00
para obter a data em diferentes formatos. (Cuidado, nem todos os idiomas atribuem o mesmo significado a cada letra - particularmente, 'M' e 'm' podem ser trocados por minutos e meses.)%
var currentDate = new Date(); var date = currentDate.getDate(); var month = currentDate.getMonth(); var year = currentDate.getFullYear();
var monthDateYear = (month+1) + '/' + date + '/' + year;
function pad(n) { return n<10 ? '0'+n : n; }
var mmddyyyy = pad(month + 1) + '/' + pad(date) + '/' + year;
var ddmmyyyy = pad(date) + '-' + pad(month + 1) + '-' + year;
var monthNames = [ 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December' ]; var dateWithFullMonthName = monthNames[month] + ' ' + pad(date) + ', ' + year;
que retorna 1º para 1, 12º para 12 e 103º para 103 etc., e o resto é simples:ordinal
var ordinalDate = ordinal(date) + ' ' + monthNames[month] + ', ' + year;
Mudando o formato da data
var daysOfWeek = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']; ordinalDateWithDayOfWeek = daysOfWeek[currentDate.getDay()] + ', ' + ordinalDate;
Usando funções de localização do objeto JavaScript Date
const myDate = new Date('Jul 21, 2013'); const dayOfMonth = myDate.getDate(); const month = myDate.getMonth(); const year = myDate.getFullYear(); function pad(n) { return n<10 ? '0'+n : n } const ddmmyyyy = pad(dayOfMonth) + '-' + pad(month + 1) + '-' + year; // '21-07-2013'
do objeto Date
método:toLocaleDateString()
const today = new Date().toLocaleDateString('en-GB', { day: 'numeric', month: 'short', year: 'numeric', });
.26 Jul 2016
funciona de maneira muito semelhante a esta, mas permite reutilizar um objeto formatador de forma que você só precise definir as opções uma vez.Intl.DateTimeFormat
, é um bom hábito sempre passar as opções de formatação, mesmo se a saída parecer boa em seu computador. Isso pode proteger a IU de interromper em localidades inesperadas com nomes de meses muito longos ou parecer estranha por causa de nomes curtos.toLocaleDateString()
const today = new Date().toLocaleDateString(undefined, { day: 'numeric', month: 'numeric', year: 'numeric', });
. Se você quiser ter certeza de que o mês e a data têm dois dígitos, basta alterar as opções:7/26/2016
const today = new Date().toLocaleDateString(undefined, { day: '2-digit', month: '2-digit', year: 'numeric', });
. Exatamente o que queríamos!
Código Resultado Descrição 07/26/2016
'4:21:38 AM' Exibir versão localizada do único tempo now.toLocaleTimeString()
'04: 21: 38 AM ' Exibir a hora localizada com base nas opções fornecidas now.toLocaleTimeString(undefined, { hour: '2-digit', minute: '2-digit', second: '2-digit', });
'22/07/2016, 4:21:38 AM' Exibir data e hora para a localidade do usuário now.toLocaleString()
'22/07/2016, 04:21' Exibir data e hora localizadas com base nas opções fornecidas Cálculo de datas e horários relativos
now.toLocaleString(undefined, { day: 'numeric', month: 'numeric', year: 'numeric', hour: '2-digit', minute: '2-digit', });
const myDate = new Date('July 20, 2016 15:00:00'); const nextDayOfMonth = myDate.getDate() + 20; myDate.setDate(nextDayOfMonth); const newDate = myDate.toLocaleString();
contém uma string localizada que representa essa data. No meu navegador, newDate
contém “09/08/2016, 3:00:00 PM”.newDate
e Date.getTime()
para trabalhar com números inteiros que representam o número de milissegundos desde uma certa época, ou seja, 1 ° de janeiro de 1970. Por exemplo, se você quiser saber quando são 17 horas agora:Date.setTime()
Comparando datas
const msSinceEpoch = (new Date()).getTime(); const seventeenHoursLater = new Date(msSinceEpoch + 17 * 60 * 60 * 1000);
const date1 = new Date('July 19, 2014'); const date2 = new Date('July 28, 2014'); if(date1 > date2) { console.log('First date is more recent'); } else { console.log('Second date is more recent'); }
const date1 = new Date('June 10, 2003'); const date2 = new Date(date1); const equalOrNot = date1 == date2 ? 'equal' : 'not equal'; console.log(equalOrNot);
.not equal
date1.getTime() == date2.getTime()
const userEnteredString = '12/20/1989'; // MM/DD/YYYY format const dateStringFromAPI = '1989-12-20T00:00:00Z'; const dateFromUserEnteredString = new Date(userEnteredString) const dateFromAPIString = new Date(dateStringFromAPI); if (dateFromUserEnteredString.getTime() == dateFromAPIString.getTime()) { transferOneMillionDollarsToUserAccount(); } else { doNothing(); }
criará uma data 1989-12-20T00: 00: 00 + 5: 45 ou 1989-12-19T18: 15: 00Z que não é o mesmo que 1989-12-20T00: 00: 00Z em termos de carimbo de hora.
new Date ('12/20/1989')
const userEnteredDate = '12/20/1989'; const parts = userEnteredDate.split('/'); const userEnteredDateISO = parts[2] + '-' + parts[0] + '-' + parts[1]; const userEnteredDateObj = new Date(userEnteredDateISO + 'T00:00:00Z'); const dateFromAPI = new Date('1989-12-20T00:00:00Z'); const result = userEnteredDateObj.getTime() == dateFromAPI.getTime(); // true
const userEnteredDate = new Date('1989-12-20'); const dateFromAPI = new Date('1989-12-20T00:00:00Z'); const result = userEnteredDate.getTime() == dateFromAPI.getTime(); // true
Encontrando a diferença entre duas datas
Encontrando o Número de Dias entre Duas Datas
const userEnteredDate = new Date('12/20/1989'); const userEnteredDateTimeStamp = Date.UTC(userEnteredDate.getFullYear(), userEnteredDate.getMonth(), userEnteredDate.getDate(), 0, 0, 0); const dateFromAPI = new Date('1989-12-20T00:00:00Z'); const result = userEnteredDateTimeStamp == dateFromAPI.getTime(); // true ...
Encontrar a idade do usuário a partir da data de nascimento
const dateFromAPI = '2016-02-10T00:00:00Z'; const now = new Date(); const datefromAPITimeStamp = (new Date(dateFromAPI)).getTime(); const nowTimeStamp = now.getTime(); const microSecondsDiff = Math.abs(datefromAPITimeStamp - nowTimeStamp); // Math.round is used instead of Math.floor to account for certain DST cases // Number of milliseconds per day = // 24 hrs/day * 60 minutes/hour * 60 seconds/minute * 1000 ms/second const daysDiff = Math.round(microSecondsDiff / (1000 * 60 * 60 * 24)); console.log(daysDiff);
const birthDateFromAPI = '12/10/1989';
Sugestões para evitar encontros infernais
Obtendo DateTime do usuário
const parts = birthDateFromAPI.split('/'); const birthDateISO = parts[2] + '-' + parts[0] + '-' + parts[1]; const birthDate = new Date(birthDateISO); const today = new Date(); let age = today.getFullYear() - birthDate.getFullYear(); if(today.getMonth()
Date
formato mesmo se você já tiver a data em um formato analisável válido. Se todos os programadores em sua equipe seguirem esta regra simples, será extremamente fácil manter o código a longo prazo, uma vez que é tão explícito quanto você pode ser com o new Date(year, month, day, hours, minutes, seconds, milliseconds)
construtor.Date
é igual a new Date(2012, 10, 12)
porque os parâmetros não especificados são padronizados para zero.new Date(2012, 10, 12, 0, 0, 0, 0)
Obtendo apenas a data
const dateFromPicker = '2012-10-12'; const timeFromPicker = '12:30'; const dateParts = dateFromPicker.split('-'); const timeParts = timeFromPicker.split(':'); const localDate = new Date(dateParts[0], dateParts[1]-1, dateParts[2], timeParts[0], timeParts[1]);
const dateFromPicker = '12/20/2012'; const dateParts = dateFromPicker.split('/'); const ISODate = dateParts[2] + '-' + dateParts[0] + '-' + dateParts[1]; const birthDate = new Date(ISODate).toISOString();
objeto com a entrada em um formato de data ISO válido (AAAA-MM-DD), o padrão será UTC em vez do fuso horário do navegador.Armazenando a Data
Date
ou toISOString()
métodos do objeto Date para converter o DateTime local em UTC.toJSON()
Exibindo a data e hora
const dateFromUI = '12-13-2012'; const timeFromUI = '10:20'; const dateParts = dateFromUI.split('-'); const timeParts = timeFromUI.split(':'); const date = new Date(dateParts[2], dateParts[0]-1, dateParts[1], timeParts[0], timeParts[1]); const dateISO = date.toISOString(); $.post('http://example.com/', {date: dateISO}, ...)
objeto.Date
ou toLocaleString()
e toLocaleDateString()
métodos ou uma biblioteca de data para exibir a hora local.toLocaleTimeString()
Quando você deve armazenar a hora local também?
const dateFromAPI = '2016-01-02T12:30:00Z'; const localDate = new Date(dateFromAPI); const localDateString = localDate.toLocaleDateString(undefined, { day: 'numeric', month: 'short', year: 'numeric', }); const localTimeString = localDate.toLocaleTimeString(undefined, { hour: '2-digit', minute: '2-digit', second: '2-digit', });
A função nos diz o número de minutos que, quando adicionado a uma determinada hora local, dá a hora UTC equivalente. Sugiro convertê-lo para o formato (+ -) hh: mm porque torna mais óbvio que é um deslocamento de fuso horário.getTimeZoneOffset()
const now = new Date(); const tz = now.gettime zoneOffset();
const sign = tz > 0 ? '-' : '+'; const hours = pad(Math.floor(Math.abs(tz)/60)); const minutes = pad(Math.abs(tz)%60); const tzOffset = sign + hours + ':' + minutes;
const localDateTime = now.getFullYear() + '-' + pad(now.getMonth()+1) + '-' + pad(now.getDate()) + 'T' + pad(now.getHours()) + ':' + pad(now.getMinutes()) + ':' + pad(now.getSeconds());
const eventDate = { utc: now.toISOString(), local: localDateTime, tzOffset: tzOffset, }
função.getHours()
const localDateString = eventDate.local; const localDate = new Date(localDateString); if(localDate.getHours() <12) { console.log('Event happened before noon local time'); }
aqui, mas ainda o armazenamos porque podemos precisar dele no futuro para fins de depuração. Na verdade, você poderia apenas enviar a diferença de fuso horário e a hora UTC apenas. Mas eu gosto de armazenar a hora local também porque você eventualmente terá que armazenar a data em um banco de dados e ter a hora local armazenada separadamente permite que você faça uma consulta direta com base em um campo em vez de ter que realizar cálculos para obter a data local.Configuração de servidor e banco de dados
É hora de um melhor manuseio de datas