Reputation: 2201
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
Upvotes: 87
Views: 83641
Reputation: 483
In date-fns, you can make:
roundToNearestMinutes(new Date(), { nearestTo: 15, roundingMethod: "ceil" })
Upvotes: 0
Reputation: 387
I use these code:
function RoundUp(intervalMilliseconds, datetime){
datetime = datetime || new Date();
var modTicks = datetime.getTime() % intervalMilliseconds;
var delta = modTicks === 0 ? 0 : datetime.getTime() - modTicks;
delta += intervalMilliseconds;
return new Date(delta);
}
function RoundDown(intervalMilliseconds, datetime){
datetime = datetime || new Date();
var modTicks = datetime.getTime() % intervalMilliseconds;
var delta = modTicks === 0 ? 0 : datetime.getTime() - modTicks;
return new Date(delta);
}
function Round(intervalMilliseconds, datetime){
datetime = datetime || new Date();
var modTicks = datetime.getTime() % intervalMilliseconds;
var delta = modTicks === 0 ? 0 : datetime.getTime() - modTicks;
var shouldRoundUp = modTicks > intervalMilliseconds/2;
delta += shouldRoundUp ? intervalMilliseconds : 0;
return new Date(delta);
}
Round to the nearest 5 minutes:
//with current datetime
var result = Round(5 * 60 * 1000);
//with a given datetime
var dt = new Date();
var result = Round(5 * 60 * 1000, dt);
Upvotes: 2
Reputation: 82192
This method is specifically for Vue.js, it takes a time, and returns to the nearest entered increment, I based this on an above answer, but this is for Vue specifically using echma-6 standards. It will return T:06:00:00, if you fed 06:05 into it. This is used specifically with vuetify's v-calendar
to choose a time in weeklyor daily format.
This answer also adds the 0 for like 06 hrs. Which is where this differs from the above answers. If you change the 30 to 15
methods: {
roundTimeAndFormat(datetime, roundTo) {
const hrsMins = datetime.split(':')
let min = ((((hrsMins[1] + 7.5) / roundTo) | 0) * roundTo) % 60
let hr = (((hrsMins[1] / 105 + 0.5) | 0) + hrsMins[0]) % 24
if (Number(hr) < 10) {
hr = ('0' + hr).slice(-2)
}
if (min === 0) {
min = ('0' + min).slice(-2)
}
return 'T' + hr + ':' + min + ':00'
}
}
You would just call:
this.roundTimeAndFormat(dateTime, 15)
And you would get the time to the nearest 15min interval. If you enter, 11:01, you'd get T11:00:00
Upvotes: 0
Reputation: 39
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));
Upvotes: 0
Reputation: 99
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);
Upvotes: 0
Reputation: 531
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;
}
Upvotes: 35
Reputation: 22876
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) )
Upvotes: 9
Reputation: 742
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
Upvotes: 0
Reputation: 6143
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
return rHr.padStart(2, '0')+':'+rMin.padStart(2, '0')
}
// USAGE //
// Round time to 15 minutes
roundTime('8:07', 15); // "08:00"
roundTime('7:53', 15); // "08:00"
roundTime('7:52', 15); // "07:45"
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}
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
Upvotes: 22
Reputation: 1394
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?
Upvotes: -1
Reputation: 105071
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).
//----
Upvotes: 120
Reputation: 43094
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);
Upvotes: 7