admin管理员组

文章数量:1418426

I'm trying to round a Date to the nearest 3, 6, 12, or 24 hours intervals (starting at midnight). Given the following inputs, I'm looking for the related output..

for 24 hours
2013-09-11 00:00:00 -> 2013-09-11 00:00:00 (no change needed)
2013-09-11 01:30:25 -> 2013-09-11 00:00:00 (rounded down)
2013-09-11 12:01:01 -> 2013-09-12 00:00:00 (rounded up)

for 12 hours
2013-09-11 00:00:00 -> 2013-09-11 00:00:00 (no change needed)
2013-09-11 12:00:00 -> 2013-09-11 12:00:00 (no change needed)
2013-09-11 11:50:57 -> 2013-09-11 12:00:00 (rounded up)
2013-09-11 12:01:00 -> 2013-09-11 12:00:00 (rounded down)
2013-09-11 22:15:48 -> 2013-09-12 00:00:00 (rounded up)

for 6 hours
2013-09-11 05:50:57 -> 2013-09-11 06:00:00 (rounded up)
2013-09-11 08:50:57 -> 2013-09-11 06:00:00 (rounded down)
2013-09-11 10:50:57 -> 2013-09-11 12:00:00 (rounded up)

for 3 hours
2013-09-11 01:50:57 -> 2013-09-11 00:00:00 (rounded down)
2013-09-11 02:50:57 -> 2013-09-11 03:00:00 (rounded up)
2013-09-11 09:40:57 -> 2013-09-11 09:00:00 (rounded down)

etc...

I keep finding all of these interesting solutions for rounding to the nearest minute, but I can't seem to fit them to my own needs. I thought I had something going using reference #2 below, but it fails miserably (/). Any ideas?

References:

  1. Round Date to nearest 15 minute interval in Flex
  2. How to round time to the nearest quarter hour in JavaScript?

I'm trying to round a Date to the nearest 3, 6, 12, or 24 hours intervals (starting at midnight). Given the following inputs, I'm looking for the related output..

for 24 hours
2013-09-11 00:00:00 -> 2013-09-11 00:00:00 (no change needed)
2013-09-11 01:30:25 -> 2013-09-11 00:00:00 (rounded down)
2013-09-11 12:01:01 -> 2013-09-12 00:00:00 (rounded up)

for 12 hours
2013-09-11 00:00:00 -> 2013-09-11 00:00:00 (no change needed)
2013-09-11 12:00:00 -> 2013-09-11 12:00:00 (no change needed)
2013-09-11 11:50:57 -> 2013-09-11 12:00:00 (rounded up)
2013-09-11 12:01:00 -> 2013-09-11 12:00:00 (rounded down)
2013-09-11 22:15:48 -> 2013-09-12 00:00:00 (rounded up)

for 6 hours
2013-09-11 05:50:57 -> 2013-09-11 06:00:00 (rounded up)
2013-09-11 08:50:57 -> 2013-09-11 06:00:00 (rounded down)
2013-09-11 10:50:57 -> 2013-09-11 12:00:00 (rounded up)

for 3 hours
2013-09-11 01:50:57 -> 2013-09-11 00:00:00 (rounded down)
2013-09-11 02:50:57 -> 2013-09-11 03:00:00 (rounded up)
2013-09-11 09:40:57 -> 2013-09-11 09:00:00 (rounded down)

etc...

I keep finding all of these interesting solutions for rounding to the nearest minute, but I can't seem to fit them to my own needs. I thought I had something going using reference #2 below, but it fails miserably (http://jsfiddle/LUwk8/2/). Any ideas?

References:

  1. Round Date to nearest 15 minute interval in Flex
  2. How to round time to the nearest quarter hour in JavaScript?
Share Improve this question edited May 23, 2017 at 10:29 CommunityBot 11 silver badge asked Sep 12, 2013 at 1:41 LangdonLangdon 20.1k18 gold badges89 silver badges107 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 3

Get the fractional hours using [get|set][Hours|Minutes|Seconds|Milliseconds](), and round that to the interval:

function roundTo(num, interval) {
    return Math.round(num / interval) * interval;
}

function roundHours(date, interval) {
    var newDate = new Date(date);
    var h = newDate.getHours() + newDate.getMinutes() / 60 + newDate.getSeconds() / 3600 + newDate.getMilliseconds() / 3600000;
    newDate.setMinutes(0);
    newDate.setSeconds(0);
    newDate.setMilliseconds(0);
    newDate.setHours(roundTo(h, interval));

    return newDate;
}

You can use the mod of the time divided by the precision,

if you want to make 1am round down to midnight,

rather than up to 3, 6 or noon.

function roundHours(precision, d){
    precision= precision || 1;
    d= d? new Date(d):new Date();
    if(d.getSeconds()>30) d.setMinutes(d.getMinutes()+1);
    if(d.getMinutes>30) hours+= 1;
    var hours= d.getHours(), diff= hours%precision;
    if(diff>precision/2) hours+= (precision-diff);
    else hours-= diff;
    d.setHours(hours, 0, 0, 0);
    return d.toLocaleString();
}

//testing precision:

var A= [], range=[3,6,12,24], d1= new Date();
for(var x= 0; x<4; x++){
    A.push('\n'+range[x]+ ' hour precision:');
    for(var i= 0; i<24; i++){
        d1.setHours(i);
        A.push(i+':  '+roundHours(range[x], d1));
    }
}
A.join('\n');

//returned value: (String)

3 hour precision:
00:  Wednesday, September 11, 2013 12:00:00 AM
01:  Wednesday, September 11, 2013 12:00:00 AM
02:  Wednesday, September 11, 2013 3:00:00 AM
03:  Wednesday, September 11, 2013 3:00:00 AM
04:  Wednesday, September 11, 2013 3:00:00 AM
05:  Wednesday, September 11, 2013 6:00:00 AM
06:  Wednesday, September 11, 2013 6:00:00 AM
07:  Wednesday, September 11, 2013 6:00:00 AM
08:  Wednesday, September 11, 2013 9:00:00 AM
09:  Wednesday, September 11, 2013 9:00:00 AM
10:  Wednesday, September 11, 2013 9:00:00 AM
11:  Wednesday, September 11, 2013 12:00:00 PM
12:  Wednesday, September 11, 2013 12:00:00 PM
13:  Wednesday, September 11, 2013 12:00:00 PM
14:  Wednesday, September 11, 2013 3:00:00 PM
15:  Wednesday, September 11, 2013 3:00:00 PM
16:  Wednesday, September 11, 2013 3:00:00 PM
17:  Wednesday, September 11, 2013 6:00:00 PM
18:  Wednesday, September 11, 2013 6:00:00 PM
19:  Wednesday, September 11, 2013 6:00:00 PM
20:  Wednesday, September 11, 2013 9:00:00 PM
21:  Wednesday, September 11, 2013 9:00:00 PM
22:  Wednesday, September 11, 2013 9:00:00 PM
23:  Thursday, September 12, 2013 12:00:00 AM

6 hour precision:
00:  Wednesday, September 11, 2013 12:00:00 AM
01:  Wednesday, September 11, 2013 12:00:00 AM
02:  Wednesday, September 11, 2013 12:00:00 AM
03:  Wednesday, September 11, 2013 12:00:00 AM
04:  Wednesday, September 11, 2013 6:00:00 AM
05:  Wednesday, September 11, 2013 6:00:00 AM
06:  Wednesday, September 11, 2013 6:00:00 AM
07:  Wednesday, September 11, 2013 6:00:00 AM
08:  Wednesday, September 11, 2013 6:00:00 AM
09:  Wednesday, September 11, 2013 6:00:00 AM
10:  Wednesday, September 11, 2013 12:00:00 PM
11:  Wednesday, September 11, 2013 12:00:00 PM
12:  Wednesday, September 11, 2013 12:00:00 PM
13:  Wednesday, September 11, 2013 12:00:00 PM
14:  Wednesday, September 11, 2013 12:00:00 PM
15:  Wednesday, September 11, 2013 12:00:00 PM
16:  Wednesday, September 11, 2013 6:00:00 PM
17:  Wednesday, September 11, 2013 6:00:00 PM
18:  Wednesday, September 11, 2013 6:00:00 PM
19:  Wednesday, September 11, 2013 6:00:00 PM
20:  Wednesday, September 11, 2013 6:00:00 PM
21:  Wednesday, September 11, 2013 6:00:00 PM
22:  Thursday, September 12, 2013 12:00:00 AM
23:  Thursday, September 12, 2013 12:00:00 AM

12 hour precision:
00:  Wednesday, September 11, 2013 12:00:00 AM
01:  Wednesday, September 11, 2013 12:00:00 AM
02:  Wednesday, September 11, 2013 12:00:00 AM
03:  Wednesday, September 11, 2013 12:00:00 AM
04:  Wednesday, September 11, 2013 12:00:00 AM
05:  Wednesday, September 11, 2013 12:00:00 AM
06:  Wednesday, September 11, 2013 12:00:00 AM
07:  Wednesday, September 11, 2013 12:00:00 PM
08:  Wednesday, September 11, 2013 12:00:00 PM
09:  Wednesday, September 11, 2013 12:00:00 PM
10:  Wednesday, September 11, 2013 12:00:00 PM
11:  Wednesday, September 11, 2013 12:00:00 PM
12:  Wednesday, September 11, 2013 12:00:00 PM
13:  Wednesday, September 11, 2013 12:00:00 PM
14:  Wednesday, September 11, 2013 12:00:00 PM
15:  Wednesday, September 11, 2013 12:00:00 PM
16:  Wednesday, September 11, 2013 12:00:00 PM
17:  Wednesday, September 11, 2013 12:00:00 PM
18:  Wednesday, September 11, 2013 12:00:00 PM
19:  Thursday, September 12, 2013 12:00:00 AM
20:  Thursday, September 12, 2013 12:00:00 AM
21:  Thursday, September 12, 2013 12:00:00 AM
22:  Thursday, September 12, 2013 12:00:00 AM
23:  Thursday, September 12, 2013 12:00:00 AM

24 hour precision:
00:  Wednesday, September 11, 2013 12:00:00 AM
01:  Wednesday, September 11, 2013 12:00:00 AM
02:  Wednesday, September 11, 2013 12:00:00 AM
03:  Wednesday, September 11, 2013 12:00:00 AM
04:  Wednesday, September 11, 2013 12:00:00 AM
05:  Wednesday, September 11, 2013 12:00:00 AM
06:  Wednesday, September 11, 2013 12:00:00 AM
07:  Wednesday, September 11, 2013 12:00:00 AM
08:  Wednesday, September 11, 2013 12:00:00 AM
09:  Wednesday, September 11, 2013 12:00:00 AM
10:  Wednesday, September 11, 2013 12:00:00 AM
11:  Wednesday, September 11, 2013 12:00:00 AM
12:  Wednesday, September 11, 2013 12:00:00 AM
13:  Thursday, September 12, 2013 12:00:00 AM
14:  Thursday, September 12, 2013 12:00:00 AM
15:  Thursday, September 12, 2013 12:00:00 AM
16:  Thursday, September 12, 2013 12:00:00 AM
17:  Thursday, September 12, 2013 12:00:00 AM
18:  Thursday, September 12, 2013 12:00:00 AM
19:  Thursday, September 12, 2013 12:00:00 AM
20:  Thursday, September 12, 2013 12:00:00 AM
21:  Thursday, September 12, 2013 12:00:00 AM
22:  Thursday, September 12, 2013 12:00:00 AM
23:  Thursday, September 12, 2013 12:00:00 AM

Here's an alternative that uses the time value. Since it's UTC, it's adjusted for the offset to make UTC like local, rounded, then the offset added back on to get a local time.

// d is a date object
function roundTo3Hrs(d) {

  // Three hours in milliseconds
  var g = 3 * 60 * 60 * 1000;

  // Get local offset
  var o = d.getTimezoneOffset() * -6e4;

  // Round to nearest 3 hrs
  var x = Math.round((+d + o)/g);

  // Return a new date object
  return new Date(x * g - o);
}

// Some (minimal) tests
var now = new Date();
now.setHours(13,29,59,999);
alert(roundTo3Hrs(now)); // 12:00

now.setHours(13,30,0,0);
alert(roundTo3Hrs(now)); // 15:00

This appeals to me as it seem efficient and could be adapted for any range to round to (1 hour, 3 hour,6 hour, etc.).

本文标签: javascriptRound to the nearest n hourStack Overflow