最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Round to the nearest n hour - Stack Overflow

programmeradmin1浏览0评论

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.).

发布评论

评论列表(0)

  1. 暂无评论