Qual é a melhor maneira de inicializar uma Data JavaScript para meia-noite?

438

Qual é a maneira mais simples de obter uma instância de nova Date (), mas definir a hora à meia-noite?

Sixty4Bit
fonte

Respostas:

871

O setHoursmétodo pode levar opcional minutes, secondse msargumentos, por exemplo:

var d = new Date();
d.setHours(0,0,0,0);

Isso definirá a hora 00:00:00.000do seu fuso horário atual . Se você quiser trabalhar no horário UTC, poderá usar o setUTCHoursmétodo

CMS
fonte
41
Para sua informação, estou executando este método (d.setHours (0,0,0,0)) em uma função de redução em 270K linhas e é mais de 20 segundos mais rápido do que em d.setHours (0); d.setMinutes (0); d.setSeconds (0); Ótima resposta @CMS!
jbnunn
32
Isso precisa ser feito em duas linhas para manter d como um objeto Date. Corrigi recentemente um bug que o fazia em uma linha: var d = new Date (). SetHours (0, 0, 0, 0). No entanto, d era então um número, não uma data desde que setHours retorna um número.
21414 Jason
9
Acabei de descobrir isso (atrasado para a parte que conheço), também precisando de uma solução de uma linha retornando um Date. Para quem procura este, resposta da @ Zon funciona perfeitamente: new Date(new Date().setHours(0,0,0,0)).
SRack
226

Só queria esclarecer que o snippet da resposta aceita fornece a meia-noite mais próxima no passado :

var d = new Date();
d.setHours(0,0,0,0); // last midnight

Se você deseja obter a meia-noite mais próxima no futuro , use o seguinte código:

var d = new Date();
d.setHours(24,0,0,0); // next midnight
Dan
fonte
6
O que acontece se hoje tiver 25 horas (os relógios se ajustam para o horário de verão)?
Qntm 6/09
8
Este é um script do lado do cliente, a meia-noite é meia-noite, apesar do horário de verão .. menção Também digno de nota .. não cada lugar do mundo usa DST (horário de verão)
chris
2
@qntm: a alteração do horário de verão é sempre aplicada às 02:00 - 04:00, para que seja apenas uma meia-noite durante esse dia :). Mas sim, 3:00 pode acontecer duas vezes durante o dia (facepalm)
Dan
@ Chris Não, quero dizer o segundo trecho. "24 horas depois da meia-noite de hoje" nem sempre é a mesma coisa que "meia-noite de amanhã". Nesses casos, o segundo trecho funciona?
Qntm 23/11
3
@qntm: Date.setHours não adiciona cegamente 24 horas, é mais inteligente. Em vez disso, ele retorna um registro de data e hora do momento, quando o relógio será exibido 24 na próxima vez. Levando em consideração a economia de tempo. Tente jogar no console você mesmo. Interessante, setHours (25) retorna o registro de data e hora dos amanhãs 01:00
Dan
68

Uma linha para configurações de objeto:

new Date(new Date().setHours(0,0,0,0));

Ao criar um elemento:

dateFieldConfig = {
      name: "mydate",
      value: new Date(new Date().setHours(0, 0, 0, 0)),
}
Zon
fonte
6
Obrigado! Eu queria saber como eu posso fazê-lo em uma única linha, porque eu estava definindo uma propriedade de objeto! Ótima resposta.
Paulo Roberto Rosa
Obrigado Zon, isso me ajudou a escrever uma única linha.
precisa saber é o seguinte
22

Só vou adicionar isso aqui, porque cheguei nesta página procurando como fazer isso no momento.js e outros também.

[Fundamentação da petição : a palavra "momento" já aparece em outro lugar nesta página, para que os mecanismos de pesquisa direcionem aqui e moment.js é amplo o suficiente para garantir que seja coberto com a frequência com que é mencionado em outras perguntas relacionadas à data do SO]

Portanto, na versão 2.0.0 e superior:

date.startOf('day');

Para versões anteriores:

date.sod();

Documentos:

http://momentjs.com/docs/#/manipulating/start-of/

andyhasit
fonte
para obter um objeto de data de volta, use-omoment(DATE_OBJECT).startOf('day').toDate();
xinthose
2
sim, vamos adicionar uma biblioteca javascript de 52kb para fazer algo que você pode fazer em 2 linhas.
Bruce Lim
19
E se você já estiver usando o moment.js por um dos muitos motivos pelos quais você pode ...? Que tal ler a lógica que dei antes de adicionar um comentário sarcástico?
andyhasit 31/03
11

Você provavelmente pode usar

new Date().setUTCHours(0,0,0,0)

se você precisar do valor apenas uma vez.

Stan
fonte
1
Isso não obtém uma instância de uma Data, conforme o OP necessário.
cobberboy
Esta é definitivamente a melhor resposta, mas precisa de uma pequena edição para retornar uma instância de uma Data. nova data (nova data (). setUTCHours (0, 0, 0, 0));
VitFL 20/04
4

Adicionando utilidade ao exemplo de @ Dan, tive a necessidade de encontrar o próximo meio-dia ou meia-noite.

var d = new Date();
if(d.getHours() < 12) {
   d.setHours(12,0,0,0); // next midnight/midday is midday
} else {
   d.setHours(24,0,0,0); // next midnight/midday is midnight
}

Isso me permitiu definir um limite de frequência para um evento, permitindo que isso acontecesse uma vez pela manhã e outra à tarde para qualquer visitante do site. A data capturada foi usada para definir a expiração do cookie.

jamis0n
fonte
4

Se o cálculo com datas no verão, geralmente causará 1 hora a mais ou uma hora a menos que a meia-noite (CEST). Isso causa 1 dia de diferença quando as datas retornam. Portanto, as datas devem arredondar para a meia-noite mais próxima. Portanto, o código será (ths para jamisOn):

    var d = new Date();
    if(d.getHours() < 12) {
    d.setHours(0,0,0,0); // previous midnight day
    } else {
    d.setHours(24,0,0,0); // next midnight day
    }
user3887038
fonte
3

Eu fiz alguns protótipos para lidar com isso para mim.

// This is a safety check to make sure the prototype is not already defined.
Function.prototype.method = function (name, func) {
    if (!this.prototype[name]) {
        this.prototype[name] = func;
        return this;
    }
};

Date.method('endOfDay', function () {
    var date = new Date(this);
    date.setHours(23, 59, 59, 999);
    return date;
});

Date.method('startOfDay', function () {
    var date = new Date(this);
    date.setHours(0, 0, 0, 0);
    return date;
});

se você não quiser a verificação de segurança, poderá usar

Date.prototype.startOfDay = function(){
  /*Method body here*/
};

Exemplo de uso:

var date = new Date($.now()); // $.now() requires jQuery
console.log('startOfDay: ' + date.startOfDay());
console.log('endOfDay: ' + date.endOfDay());
Mike
fonte
2

Caso você já possua o d3.js. como uma dependência em seu projeto, ou não se importe de trazê-lo, o d3-time (a biblioteca do d3.js. é modular a partir da v4.0.0 ) possui Intervalos .

Eles podem ser úteis ao definir datas com valores "padrão", por exemplo, meia-noite, 0,00 segundos, o primeiro do mês etc.

var d = new Date(); // Wed Aug 02 2017 15:01:07 GMT+0200 (CEST)
d3.timeHour(d) // Wed Aug 02 2017 00:00:00 GMT+0200 (CEST)
d3.timeMonth(d) // Tue Aug 01 2017 00:00:00 GMT+0200 (CEST)
Peemster
fonte
Portanto, notei uma tendência nas perguntas relacionadas ao JavaScript postadas no SO: independentemente da complexidade das soluções apresentadas usando JS nativo, qualquer resposta que resolva o problema com a ajuda de uma biblioteca externa será inevitavelmente em algum momento diminuída. Percebendo isso, tomei o cuidado de postar minha resposta com o prefácio rápido: Caso você já tenha o exemplo.js como uma dependência . E, no entanto, ainda assim, o usuário SO anônimo, com voto negativo? isso dói, cara: '- (
Peemster
Descobri que essa resposta não deveria ser rejeitada, especialmente porque a que propõe o uso do moment.js tem 16 votos positivos (no momento em que escrevemos esse comentário). Ele resolve o problema de uma maneira muito concisa e não tão óbvia.
Lukeatdesignworks 26/02