I have dates in different formats like these:
2022-03-13T23:00:00.000Z
1647817200000
I want to round the date to the nearest date basically
2022-03-13T23:00:00.000Z should be 2022-03-14T00:00:00.000Z
and something like 2022-03-14T01:00:00.000Z should be 2022-03-14T00:00:00.000Z
The general rule for rounding is Math.round(N/x)*x where N is a number you want to round and x is what you want to round to.
As Date.valueOf() returns a number of milliseconds you can simply round that to the number of milliseconds in a day.
const OneDay = 86400000
const roundToNearestDay = d => new Date((Math.round(d.valueOf()/OneDay)*OneDay));
const morning = new Date("2022-03-13T11:00:00.000Z");
const evening = new Date("2022-03-13T23:00:00.000Z")
console.log(roundToNearestDay(morning))
console.log(roundToNearestDay(evening))
Having parsed the value to a Date, you can then just test if the hours are < 12, set to the time to 0:00:00 and if >=12, set to 24:00:00 (i.e. 0:00:00 the next day).
The following rounds the UTC day as that's what the OP infers:
function roundUTCDay(d) {
return new Date(Date.UTC(d.getUTCFullYear(), d.getUTCMonth(), d.getUTCDate() + (d.getUTCHours() < 12 ? 0 : 1)));
}
// Examples
['2022-03-13T11:59:59.999Z', // round down
'2022-03-13T12:00:00.000Z', // round up
'2022-03-13T23:00:00.000Z', // round up
1647817200000 // round up
].forEach(d => {
d = new Date(d);
console.log(d.toISOString() + '\n' +
roundUTCDay(d).toISOString())
});
This can be done in a UTC or local context, perhaps passing a "use UTC" parameter that defaults to true:
function roundToDay(date = new Date(), useUTC = true) {
let d = new Date(+date);
let x = useUTC? 'UTC' : '';
d[`set${x}Hours`](d[`get${x}Hours`]() < 12? 0 : 24,
0,0,0);
return d;
}
// Examples
['2022-03-13T11:59:59.999Z',
'2022-03-13T12:00:00.000Z',
'2022-03-13T23:00:00.000Z',
1647817200000
].forEach(d => {
d = new Date(d);
console.log(
`Round local:\n${d.toString()}\n${roundToDay(new Date(d), false).toString()}` +
`\nRound UTC:\n${d.toISOString()}\n${roundToDay(new Date(d)).toISOString()}`
);
});
The above relies on parsing the value to a date first. The built–in parser is only used because the input timestamps are supported by ECMA-262.