# How to round time to the nearest quarter hour in JavaScript?

For example:

``````Given time: 08:22 => Rounded to: 08:15

Given time: 08:23 => Rounded to: 08:30
``````

Should be pretty simple. But all I was able to produce is lengthy, not very good code to solve the issue. My mind's just gone blank.

Regards Given that you have hours and minutes in variables (if you don't you can get them from the `Date` instance anyway by using `Date` instance functions):

``````var m = (parseInt((minutes + 7.5)/15) * 15) % 60;
var h = minutes > 52 ? (hours === 23 ? 0 : ++hours) : hours;
``````

minutes can as well be calculated by using `Math.round()`:

``````var m = (Math.round(minutes/15) * 15) % 60;
``````

or doing it in a more javascript-sophisticated expression without any functions:

``````var m = (((minutes + 7.5)/15 | 0) * 15) % 60;
var h = ((((minutes/105) + .5) | 0) + hours) % 24;
``````

You can check the jsPerf test that shows `Math.round()` is the slowest of the three while mainly the last one being the fastest as it's just an expression without any function calls (no function call overhead i.e. stack manipulation, although native functions may be treated differently in Javascript VM). //---- This function round the time to the nearest quarter hour.

``````function roundTimeQuarterHour(time) {
var timeToReturn = new Date(time);

timeToReturn.setMilliseconds(Math.round(timeToReturn.getMilliseconds() / 1000) * 1000);
timeToReturn.setSeconds(Math.round(timeToReturn.getSeconds() / 60) * 60);
timeToReturn.setMinutes(Math.round(timeToReturn.getMinutes() / 15) * 15);
return timeToReturn;
}
`````` ## With Time String

Here is a method that will round a time string like the one you presented. Eg "08:22"

``````let roundTime = (time, minutesToRound) => {

let [hours, minutes] = time.split(':');
hours = parseInt(hours);
minutes = parseInt(minutes);

// Convert hours and minutes to time in minutes
time = (hours * 60) + minutes;

let rounded = Math.round(time / minutesToRound) * minutesToRound;
let rHr = ''+Math.floor(rounded / 60)
let rMin = ''+ rounded % 60

}

// USAGE //

// Round time to 15 minutes
roundTime('8:07', 15); // "08:00"
roundTime('7:53', 15); // "08:00"
roundTime('7:52', 15); // "07:45"
``````

## With Hours and Minutes Already Split Up

You can use this method if you don't need to parse out the hour and minute strings like your example shows

``````let roundTime = (hours, minutes, minutesToRound) => {

// Convert hours and minutes to minutes
time = (hours * 60) + minutes;
let rounded = Math.round(time / minutesToRound) * minutesToRound;

let roundedHours = Math.floor(rounded / 60)
let roundedMinutes = rounded % 60

return { hours: roundedHours, minutes: roundedMinutes }
}

// USAGE //

// Round time to 15 minutes
roundTime(7, 52, 15); // {hours: 7, minutes: 45}
roundTime(7, 53, 15); // {hours: 8, minutes: 0}
roundTime(1, 10, 15); // {hours: 1, minutes: 15}
``````

## With Existing Date Object

Or, if you are looking to round an already existing date object to the nearest x minutes, you can use this method.

If you don't give it any date it will round the current time. In your case, you can round to the nearest 15 minutes.

``````let getRoundedDate = (minutes, d=new Date()) => {

let ms = 1000 * 60 * minutes; // convert minutes to ms
let roundedDate = new Date(Math.round(d.getTime() / ms) * ms);

return roundedDate
}

// USAGE //

// Round existing date to 5 minutes
getRoundedDate(15, new Date()); // 2018-01-26T00:45:00.000Z

// Get current time rounded to 30 minutes
getRoundedDate(30); // 2018-01-26T00:30:00.000Z
`````` The code here is a little verbose but I'm sure you'll see how you could combine the lines to make this shorter. I've left it this way to clearly show the steps:

``````var now = new Date();
var mins = now.getMinutes();
var quarterHours = Math.round(mins/15);
if (quarterHours == 4)
{
now.setHours(now.getHours()+1);
}
var rounded = (quarterHours*15)%60;
now.setMinutes(rounded);
document.write(now);
`````` Divide by 9e5 milliseconds (15 * 60 * 1000), round, and multiply back by 9e5 :

``````const roundToQuarter = date => new Date(Math.round(date / 9e5) * 9e5)

console.log( roundToQuarter(new Date("1999-12-31T23:52:29.999Z")) ) // 1999-12-31T23:45:00

console.log( roundToQuarter(new Date("1999-12-31T23:52:30.000Z")) ) // 2000-01-01T00:00:00

console.log( roundToQuarter(new Date) )`````` Another one with date-fns (not mandatory)

``````import {getMinutes, setMinutes, setSeconds, setMilliseconds} from 'date-fns'

let date = new Date();
let min = getMinutes(date);
let interval = 3  // in minutes
let new_min = min - min%interval + interval;
let new_date = setMilliseconds(setSeconds(setMinutes(date,new_min),0),0)

console.log('Orignal Date : ' + date);
console.log('Original Minute : ' + min);
console.log('New Minute : ' + new_min);
console.log('New Date : ' + new_date);
`````` Might help others. For any language. Mainly trick with round function.

``````roundedMinutes = yourRoundFun(Minutes / interval) * interval
``````

E.g. The interval could be 5 minutes, 10 minutes, 15 minutes, 30 minutes. Then rounded minutes can be reset to the respective date.

``````yourDateObj.setMinutes(0)
yourDateObj.setMinutes(roundedMinutes)
``````

also if required then

``````yourDateObj.setSeconds(0)
yourDateObj.setMilliSeconds(0)
``````

Simple? There is an NPM package `@qc/date-round` that can be used. Given that you have a `Date` instance to be rounded

``````import { round } from '@qc/date-round'

const dateIn = ...; // The date to be rounded
const interval = 15 * 60 * 1000; // 15 minutes (aka quarter hour)
const dateOut = round(dateIn, interval)
``````

Then you can use `date-fns` to format the date

``````import format from 'date-fns/format';

console.log(format(dateOut, 'HH:mm')) // 24-hr
console.log(format(dateOut, 'hh:mm a')) // 12-hr
`````` Pass the interval in milliseconds get the next cycle in roundUp order

Example if I want next 15 minute cycle from current time then call this method like *calculateNextCycle(15 * 60 * 1000);*

Samething for quarter hour pass the interval

``````function calculateNextCycle(interval) {
const timeStampCurrentOrOldDate = Date.now();
const timeStampStartOfDay = new Date().setHours(0, 0, 0, 0);
const timeDiff = timeStampCurrentOrOldDate - timeStampStartOfDay;
const mod = Math.ceil(timeDiff / interval);
return new Date(timeStampStartOfDay + (mod * interval));
}

console.log(calculateNextCycle(15 * 60 * 1000));``````