¿Cuál es la mejor manera de inicializar una fecha de JavaScript a medianoche?

441

¿Cuál es la forma más sencilla de obtener una instancia de nueva Fecha () pero establecer la hora a medianoche?

Sixty4Bit
fuente

Respuestas:

877

El setHoursmétodo puede tomar opcional minutes, secondsy msargumentos, por ejemplo:

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

Eso establecerá la hora 00:00:00.000de su zona horaria actual , si desea trabajar en hora UTC, puede usar el setUTCHoursmétodo.

CMS
fuente
42
FYI, estoy ejecutando este método (d.setHours (0,0,0,0)) en una función de reducción en 270K filas, y es más de 20 segundos más rápido que hacer d.setHours (0); d.setMinutes (0); d.setSeconds (0); Gran respuesta @CMS!
jbnunn
32
Esto debe hacerse en dos líneas para mantener d como un objeto Date. Recientemente arreglé un error que lo hizo en una línea: var d = new Date (). SetHours (0, 0, 0, 0). Sin embargo, d era un número, no una fecha, ya que setHours devuelve un número.
Jason
99
Acabo de encontrar esto (tarde en la fiesta que conozco), y también necesito una solución de una línea que devuelva una Fecha. Para aquellos que buscan esto, @ respuesta de Zon funciona perfectamente: new Date(new Date().setHours(0,0,0,0)).
SRack
227

Solo quería aclarar que el fragmento de la respuesta aceptada da la medianoche más cercana en el pasado :

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

Si desea obtener la medianoche más cercana en el futuro , use el siguiente código:

var d = new Date();
d.setHours(24,0,0,0); // next midnight
Dan
fuente
66
¿Qué sucede si hoy dura 25 horas (los relojes se ajustan para el horario de verano)?
qntm
8
Esta es una secuencia de comandos del lado del cliente, la medianoche es medianoche, a pesar del horario de verano. Mención digna de mención ... no todos los lugares del mundo usan DST (horario de verano)
Chris
2
@qntm: el cambio de horario de verano siempre se aplica a las 2 am-4am, por lo que será solo una medianoche durante ese día :). Pero sí, las 3 a.m. pueden suceder dos veces durante el día (facepalm)
Dan
@ Chris No, me refiero al segundo fragmento. "24 horas después de la medianoche de hoy" no siempre es lo mismo que "medianoche mañana". En estos casos, ¿funciona el segundo fragmento?
qntm
3
@qntm: Date.setHours no agrega ciegamente 24 horas, es más inteligente. En cambio, devuelve una marca de tiempo del momento, cuando el reloj mostrará 24 la próxima vez. Teniendo en cuenta el ahorro de tiempo. Intenta jugar en la consola tú mismo. Interesante, setHours (25) devuelve la marca de tiempo de la mañana 1am
Dan
68

Una línea para configuraciones de objetos:

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

Al crear un elemento:

dateFieldConfig = {
      name: "mydate",
      value: new Date(new Date().setHours(0, 0, 0, 0)),
}
Zon
fuente
66
¡Gracias! Me preguntaba cómo puedo hacerlo en una sola línea porque estaba configurando una propiedad de objeto. Gran respuesta.
Paulo Roberto Rosa
Gracias Zon, esto me ayudó a escribirlo en una sola línea.
HungrySoul
22

Solo voy a agregar esto aquí porque llegué a esta página buscando cómo hacer esto en moment.js y otros también pueden hacerlo.

[Justificación: la palabra "momento" ya aparece en otra parte de esta página, por lo que los motores de búsqueda dirigen aquí, y moment.js está lo suficientemente extendido como para garantizar que se cubra la frecuencia con que se menciona en otras preguntas de SO relacionadas con la fecha]

Entonces, en la versión 2.0.0 y superior:

date.startOf('day');

Para versiones anteriores:

date.sod();

Documentos:

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

andyhasit
fuente
para recuperar un objeto de fecha, use estomoment(DATE_OBJECT).startOf('day').toDate();
xinthose
2
yay, agreguemos una biblioteca de 52kb javascript para hacer algo que puede hacer en 2 líneas.
Bruce Lim
19
¿Y qué pasa si ya estás usando moment.js por una de las muchas buenas razones por las que podrías ...? ¿Qué tal leer el razonamiento que di antes de agregar un comentario sarcástico?
andyhasit
11

Probablemente puedas usar

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

si necesita el valor solo una vez.

Stan
fuente
1
Esto no obtiene una instancia de una Fecha, como lo requiere el OP.
cobberboy
Esta es definitivamente la mejor respuesta, pero necesita una pequeña edición para devolver una instancia de una fecha. nueva Fecha (nueva Fecha (). setUTCHours (0, 0, 0, 0));
VitFL
4

Añadiendo utilidad al ejemplo de @ Dan, tuve la necesidad de encontrar el próximo mediodía o medianoche.

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
}

Esto me permitió establecer un límite de frecuencia para un evento, solo permitiendo que ocurriera una vez por la mañana y otra por la tarde para cualquier visitante de mi sitio. La fecha capturada se usó para establecer la caducidad de la cookie.

jamis0n
fuente
4

Si el cálculo con fechas en verano ocasionará con frecuencia 1 uur más o una hora menos que la medianoche (CEST). Esto causa una diferencia de 1 día cuando regresan las fechas. Entonces las fechas tienen que redondearse a la medianoche más cercana. Entonces el código será (ths to 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
    }
usuario3887038
fuente
3

He hecho un par de prototipos para manejar esto por mí.

// 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;
});

si no desea el cheque de seguridad, puede usar

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

Ejemplo de uso:

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

En caso de que ya tenga d3.js como una dependencia en su proyecto, o no le importe incorporarlo, d3-time (la biblioteca d3.js es modular a partir de v4.0.0 ) tiene intervalos .

Pueden resultar útiles al establecer fechas en valores "predeterminados", por ejemplo, medianoche, 0.00 segundos, el primero del mes, 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
fuente
Así que he notado una tendencia en las preguntas relacionadas con JavaScript publicadas en SO: no importa la complejidad de las soluciones presentadas utilizando JS nativo, cualquier respuesta que aborde el problema con la ayuda de una biblioteca externa inevitablemente en algún momento será rechazada. Al darme cuenta de esto, me encargué de publicar mi respuesta con el prefacio rápido: en caso de que ya tenga example.js como dependencia . ¿Y aún así, el usuario anónimo SO anónimo? eso duele, hombre: '- (
Peemster
Sentí que esta respuesta no debería ser rechazada, especialmente porque la que propone el uso de moment.js tiene 16 votos (al momento de escribir este comentario). Resuelve el problema de una manera muy concisa y no tan obvia.
lukeatdesignworks