Home > other >  Problem with Date timestamp on Javascript
Problem with Date timestamp on Javascript

Time:09-17

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:

use example

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.

  • Related