【问题标题】:Round to the nearest n hour四舍五入到最近的 n 小时
【发布时间】:2013-09-12 01:41:42
【问题描述】:

我正在尝试将日期四舍五入到最接近的 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. Round Date to nearest 15 minute interval in Flex
  2. How to round time to the nearest quarter hour in JavaScript?

【问题讨论】:

    标签: javascript


    【解决方案1】:

    使用[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;
    }
    

    【讨论】:

    • 很好...setHours 非常方便。我要提一些关于roundTo 工作不正常的事情...感谢您的编辑。
    【解决方案2】:

    你可以使用时间除以精度的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
    

    【讨论】:

      【解决方案3】:

      这是使用时间值的替代方法。由于它是 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 小时等)。

      【讨论】:

        猜你喜欢
        • 2020-04-24
        • 1970-01-01
        • 1970-01-01
        • 2018-09-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多