Home > Software design >  Modify "Round to nearest interval" function so that it works with intervals above 1 hour
Modify "Round to nearest interval" function so that it works with intervals above 1 hour

Time:09-01

Consider this function that rounds down to the nearest interval:

function roundToNearest(value, interval) {
  return Math.floor(value/interval) * interval;
}

Date.now()

> Thu Sep 01 2022 05:38:11 GMT 0300 (Eastern European Summer Time)

Now run it with 5 minutes:

new Date(roundToNearest(Date.now(), 1000*60*5))

> Thu Sep 01 2022 05:35:00 GMT 0300 (Eastern European Summer Time)

15 minutes:

new Date(roundToNearest(Date.now(), 1000*60*15))

> Thu Sep 01 2022 05:30:00 GMT 0300 (Eastern European Summer Time)

1 hour:

new Date(roundToNearest(Date.now(), 1000*60*60*1))

> Thu Sep 01 2022 05:00:00 GMT 0300 (Eastern European Summer Time)

2 hours:

new Date(roundToNearest(Date.now(), 1000*60*60*2))

>Thu Sep 01 2022 03:00:00 GMT 0300 (Eastern European Summer Time) (should be 04:00:00)

Intervals 1 hour and below return the expected results, but 2 hours (and any interval above 2 hours) does not (04:00:00 was expected for 2 hours, for example). How can I modify it so that it works on intervals above 1 hour?

CodePudding user response:

You may pass over for the time difference in your timezone. Let's subtract 0300 from 03:00:00. I don't prove it correct, but the following might work for you:

new Date(roundToNearest(Date.now()   1000*60*60*3, 1000*60*60*2) - 1000*60*60*3)

CodePudding user response:

I think what you need here is to round the time since midnight. That is, if the time is 05:30 with 2 hour rounding you want 04:00, or for 6 hour rounding you want 00:00.

We get the interval since local midnight, round to the desired number, then add to midnight. We'll create a few helper functions getMidnight() and getTimeSinceMidnight().

We'll then combine to create a roundSinceMidnight() function.

function roundSinceMidnight(date, interval) {
    return roundToNearest(getTimeSinceMidnight(date), interval)   getMidnight(date);
}

function roundToNearest(value, interval) {
  return Math.floor(value/interval) * interval;
}

function getMidnight(date) {
    const d = new Date(date); // date could be a Date object or ms since 1970...
    return new Date(d.getFullYear(), d.getMonth(), d.getDate()).getTime(); 
}

function getTimeSinceMidnight(date) {
    return date - getMidnight(date);
}

console.log('1 hour: ', new Date(roundSinceMidnight(Date.now(), 1000*60*60*1)).toTimeString())
console.log('2 hours:', new Date(roundSinceMidnight(Date.now(), 1000*60*60*2)).toTimeString())
console.log('4 hours:', new Date(roundSinceMidnight(Date.now(), 1000*60*60*4)).toTimeString())
console.log('6 hours:', new Date(roundSinceMidnight(Date.now(), 1000*60*60*6)).toTimeString())
.as-console-wrapper { max-height: 100% !important; }

  • Related