I have a function that set the date to UTC 0. Like this:
const removeDateTimestamp = (date) => {
return new Date(
date.getUTCFullYear(),
date.getUTCMonth(),
date.getUTCDate(),
0,
0,
0,
0
);
};
But the problem is when I use it. If I use on my console on the browser I get this result:
Sat May 15 2021 00:00:00 GMT 0200 (hora de verano de Europa central)
But when I run tests on Jest I got this other result:
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
);
});
In the first example I have Sat May 15 2021 00:00:00 GMT 0200 when the passed day is 16, and in the second example with same day is 14.
I'm clearly overlooking something important but I don't see it.
CodePudding user response:
The Date
constructor interprets its arguments in local time. To get a Date
instance from parts using UTC, use Date.UTC
(which returns a milliseconds-since-The-Epoch value, so if you want a Date
instance, you pass the result to new Date
):
const removeDateTimestamp = (date) => {
return new Date(
Date.UTC(
date.getUTCFullYear(),
date.getUTCMonth(),
date.getUTCDate(),
0,
0,
0,
0
)
);
};
FWIW, here's another way to do the same thing you're doing above:
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;
};
I should also mention there's a way to do this with the new Temporal API that will be making its way into the standard library soon (already at Stage 3).
CodePudding user response:
T.J. has the detailed answer and I can't find a suitable duplicate so I'll post this as a simplification that fixes your issue.
Since ECMAScript days always have exactly 8.64e7 ms, you can just subtract the remainder after dividing by ms in one day, e.g.
const getUTCTimeZero = (date) => new Date(date - date % 8.64e7);
console.log(getUTCTimeZero(new Date()))
The name removeDateTimestamp is a bit misleading as a timestamp is any string or number (or value perhaps) that represents a date or time. You seem to just want to set the time to zero, hence the different name.