93

Using a Date() instance, how might I round a time to the nearest five minutes?

For example: if it's 4:47 p.m. it'll set the time to 4:45 p.m.

Jick Lee
  • 989
  • 1
  • 6
  • 8
  • 1
    Are you using `Date` instances or strings? – Šime Vidas May 28 '12 at 19:12
  • THanks for the quick response mates, yes i am using Date() instance. – Jick Lee May 28 '12 at 19:13
  • 3
    There's no need to edit the question title to mark the question as "Solved", that can be indicated by selecting the right answer :) – Gareth May 28 '12 at 19:27
  • 1
    Possible duplicate of [How to round time to the nearest quarter hour in JavaScript?](https://stackoverflow.com/questions/4968250/how-to-round-time-to-the-nearest-quarter-hour-in-javascript) – Liam Jan 18 '19 at 10:30

10 Answers10

266

That's pretty simple if you already have a Date object:

var coeff = 1000 * 60 * 5;
var date = new Date();  //or use any other date
var rounded = new Date(Math.round(date.getTime() / coeff) * coeff)
Tomasz Nurkiewicz
  • 334,321
  • 69
  • 703
  • 674
  • 28
    @Jick If an answer works for you then you should click the green tick to mark it as an accepted answer. That way, both you and the answerer get a little boost to your reputation and you get a nice fuzzy feeling inside – Gareth May 28 '12 at 19:26
  • 25
    In case you want to round it up all the time. Just use `Math.ceil` instead of `Math.round`. That way you can always round up by 10 minutes for instance. – Hendrik Dec 01 '14 at 23:11
  • You don't even need to use `getTime` as it will use `valueOf` implicitly, eg `new Date(Math.round(date / coeff) * coeff)` – Phil Mar 21 '18 at 06:29
  • TypeScript complains about left-hand arithmetic, so adding getTime() actually fixes that error. Not that I advocate for the usage of TS for normal applications, but I'm building a financial application so I am being extra careful. – SacWebDeveloper Dec 27 '20 at 20:47
21

Round to nearest x minutes

Here is a method that will round a date object to the nearest x minutes, or if you don't give it any date it will round the current time.

function 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(5, new Date()); // 2018-01-26T00:45:00.000Z

// Get current time rounded to 30 minutes
getRoundedDate(30); // 2018-01-26T00:30:00.000Z
joshuakcockrell
  • 5,200
  • 2
  • 34
  • 47
  • Note: this is working on the UTC time. It does not matter for truncating to the nearest five minutes but won't work if truncating to the hour in local time since some time-zones are not full hours. – Eli Algranti Aug 26 '20 at 07:57
18

With ES6 and partial functions it can be elegant. Choose if need to round to closest or always down/up:

const roundTo = roundTo => x => Math.round(x / roundTo) * roundTo;    
const roundDownTo = roundTo => x => Math.floor(x / roundTo) * roundTo;
const roundUpTo = roundTo => x => Math.ceil(x / roundTo) * roundTo;

const roundTo5Minutes = roundTo(1000 * 60 * 5);
const roundDownTo5Minutes = roundDownTo(1000 * 60 * 5);
const roundUpTo5Minutes = roundUpTo(1000 * 60 * 5);

const now = new Date();
const msRound = roundTo5Minutes(now)
const msDown = roundDownTo5Minutes(now)
const msUp = roundUpTo5Minutes(now)

console.log(now);
console.log(new Date(msRound));
console.log(new Date(msDown));
console.log(new Date(msUp));
peter.bartos
  • 11,855
  • 3
  • 51
  • 62
6

I know it is bit late for answer but maybe it can help someone. If you take the minutes by the following

new Date().getMinutes()

you can take the last 5 minutes by

new Date().getMinutes() - (new Date().getMinutes()%5)
Sam
  • 145
  • 1
  • 15
user3767296
  • 239
  • 4
  • 5
5

Date-fns now has a function which will round minutes on dates. See https://date-fns.org/v2.21.3/docs/roundToNearestMinutes

const roundToNearestMinutes = require('date-fns/roundToNearestMinutes')
// OR: import roundToNearestMinutes from 'date-fns/roundToNearestMinutes'
console.log(roundToNearestMinutes(new Date(), {nearestTo: 5}));
// e.g. 2021-05-19T22:45:00.000Z
phhu
  • 1,462
  • 13
  • 33
3

Probably less efficient but here's another alternative:

debug('Current timestamp:', timestamp);

timestamp.setMilliseconds(0);
timestamp.setSeconds(0);
timestamp.setMinutes(Math.round(timestamp.getMinutes() / 5) * 5);

debug('Rounded timestamp:', timestamp);
Current timestamp: 2019-10-22T09:47:17.989Z
Rounded timestamp: 2019-10-22T09:45:00.000Z
Malvineous
  • 25,144
  • 16
  • 116
  • 151
1

Use this method to get the next 5 minute cycle using pure JS

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(5 * 60 * 1000)); // pass in milliseconds
0

recently found a very efficient way to round off the date to a timeframe

in short:

// minutes
var tf = 15; // 5,10,13,15, 60, - what ever you want
var dt = DateTime.UtcNow;
var minues = dt.TimeOfDay.TotalMinutes; // use TotalMinutes, TotalSecibds, TotalMillisecons  and etc
var roundedMinutes = (minues - (minues%tf));
var roundedDate = dt.Date.AddMinutes(a);

I bit of my testing in LINQPad

// minutes
var tf = 15; // 5,10,13,15, 60, - what ever you want
var dt = DateTime.UtcNow;
var minues = dt.TimeOfDay.TotalMinutes;
dt.Dump();
minues.Dump();
(ms%tf).Dump();
var a = (minues - (minues%tf));
a.Dump();
dt.Date.AddMinutes(a).Dump();

output:

13.07.2018 7:43:58 - current date
463,981443103333 - total mins
13,9814431033333 - rest
450 - rounded minutes value
13.07.2018 7:30:00 - rounded date
Vladimir Semashkin
  • 1,270
  • 1
  • 10
  • 21
0

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 = 5 * 60 * 1000; // 5 minutes
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
Danny Hurlburt
  • 674
  • 1
  • 8
  • 15
0

One line solution (round up or down):

const fixedTime = (isRoundUp ? Math.ceil : Math.floor)(time / 60_000 / minutesRange)) * 60_000 * minutesRange;

// minutesRange: number -> 1, 5, 15, 30, etc // minutes
// isRoundUp: boolean
// time: number // millis
I.G. Pascual
  • 5,818
  • 5
  • 42
  • 58