舍入到最接近的 n 小时



我正在尝试将日期四舍五入到最接近的 3、6、12 或 24 小时间隔(从午夜开始)。 鉴于以下输入,我正在寻找相关的输出。

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

我一直在寻找所有这些有趣的解决方案,以四舍五入到最接近的分钟,但我似乎无法将它们适合我自己的需求。 我以为我在下面的参考 #2 中有一些事情要做,但它惨遭失败(http://jsfiddle.net/LUwk8/2/)。 有什么想法吗?

引用:

  1. Flex 中将日期舍入到最接近的 15 分钟间隔
  2. 如何在 JavaScript 中将时间舍入到最接近的一刻钟?

使用 [get|set][Hours|Minutes|Seconds|Milliseconds]() 获取小数小时数,并将其四舍五入到间隔:

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;
}

您可以使用时间除以精度的 mod,

如果你想让凌晨 1 点四舍五入到午夜,

而不是最多 3、6 或中午。

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();
}

测试精度:

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');

返回值:(字符串)

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

下面是使用时间值的替代方法。由于它是 UTC,因此会针对偏移量进行调整,使 UTC 像本地一样,四舍五入,然后将偏移量添加回来以获得本地时间。

// 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

这吸引了我,因为它看起来很有效,并且可以适应任何范围(1 小时、3 小时、6 小时等)。

最新更新