Tengo una función que establece la fecha en UTC 0. Me gusta esto:
const removeDateTimestamp = (date) => { return new Date( date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate(), 0, 0, 0, 0 ); };Pero el problema es cuando lo uso. Si uso en mi consola en el navegador obtengo este resultado:
Sáb 15 de mayo de 2021 00:00:00 GMT+0200 (hora de verano de Europa central)
Pero cuando realicé pruebas en Jest, obtuve este otro resultado:
Received has type: date Received has value: 2021-05-14T22:00:00.000Z it("removeDateTimestamp", () => { expect(removeDateTimestamp(new Date(2021, 4, 16))).toMatch( /2021-05-16T00:00:00.000Z/i ); });En el primer ejemplo, tengo el sábado 15 de mayo de 2021 a las 00:00:00 GMT+0200 cuando el día transcurrido es el 16, y en el segundo ejemplo con el mismo día es el 14.
Claramente estoy pasando por alto algo importante pero no lo veo.
El constructor Date interpreta sus argumentos en hora local . Para obtener una instancia de Date de partes que usan UTC, use Date.UTC (que devuelve un valor de milisegundos desde la época, por lo que si desea una instancia de Date , pasa el resultado a la new Date ):
const removeDateTimestamp = (date) => { return new Date( Date.UTC( date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate(), 0, 0, 0, 0 ) ); };FWIW, aquí hay otra forma de hacer lo mismo que estás haciendo arriba:
const removeDateTimestamp = (date) => { const newDate = new Date(+date); // Clone the date -- the `+` is important // on some JavaScript engines newDate.setUTCHours(0, 0, 0, 0); return newDate; };También debo mencionar que hay una manera de hacer esto con la nueva API temporal que pronto llegará a la biblioteca estándar (ya en la Etapa 3).
TJ tiene la respuesta detallada y no puedo encontrar un duplicado adecuado, así que publicaré esto como una simplificación que soluciona su problema.
Dado que los días de ECMAScript siempre tienen exactamente 8,64e7 ms, puede restar el resto después de dividir por ms en un día, por ejemplo
const getUTCTimeZero = (date) => new Date(date - date % 8.64e7); console.log(getUTCTimeZero(new Date()))El nombre removeDateTimestamp es un poco engañoso ya que una marca de tiempo es cualquier cadena o número (o quizás un valor) que representa una fecha u hora. Parece que solo desea establecer el tiempo en cero, de ahí el nombre diferente.