如何在 JavaScript 中将时间四舍五入到最近的四分之一小时?

IT技术 javascript time
2021-02-06 09:33:38

例如:

Given time: 08:22 => Rounded to: 08:15

Given time: 08:23 => Rounded to: 08:30

应该很简单。但是我所能产生的只是冗长的,不是很好的代码来解决这个问题。我的脑子简直一片空白。

问候

6个回答

鉴于变量中有小时和分钟(如果没有,则Date无论如何都可以使用Date实例函数实例中获取它们):

var m = (parseInt((minutes + 7.5)/15) * 15) % 60;
var h = minutes > 52 ? (hours === 23 ? 0 : ++hours) : hours;

分钟也可以通过使用来计算Math.round()

var m = (Math.round(minutes/15) * 15) % 60;

或者在没有任何函数的更复杂的 javascript 表达式中执行此操作:

var m = (((minutes + 7.5)/15 | 0) * 15) % 60;
var h = ((((minutes/105) + .5) | 0) + hours) % 24;

您可以检查 jsPerf 测试,该测试显示Math.round()是三个中最慢的,而主要是最后一个是最快的,因为它只是一个没有任何函数调用的表达式(没有函数调用开销,即堆栈操作,尽管在 Javascript VM 中可能会以不同的方式处理本机函数)。//----

由于您不会在几小时后使用,或者需要 ++ 的副作用,因此只需将 hours+1 放入并避免所有问题。
2021-03-22 09:33:38
@evelyn:你说得对。我编辑了我的代码。感谢您指出如此隐晦的缺陷,它可能会让许多没有经验的开发人员感到困惑。
2021-03-23 09:33:38
@MichaelRushton:谢谢迈克。我还添加了一个对许多人来说可能过于复杂的无函数计算,但它可能是三者中最快的。
2021-03-26 09:33:38
在我的情况下,速度不是问题。这里不用担心。谢谢你的帮助。
2021-03-30 09:33:38
这应该是++hours而不是hours++就像当前形式hour在该行执行后递增,这意味着h变量获得未递增/不正确的值。
2021-04-11 09:33:38

此函数将时间四舍五入到最接近的一刻钟。

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;
}
你是这种方法的英雄!对于像我这样需要接下来 15 分钟的人,您可以使用“Math.ceil”代替
2021-04-01 09:33:38
你不能只设置毫秒(0)和设置秒(0)吗?尽管如此,还是喜欢你的解决方案
2021-04-13 09:33:38

带时间字符串

这是一种将像您提供的那样舍入时间字符串的方法。例如“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"

小时和分钟已经分开

如果您不需要像示例所示那样解析小时和分钟字符串,则可以使用此方法

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}

使用现有日期对象

或者,如果您希望将已存在的日期对象四舍五入到最接近的 x 分钟,则可以使用此方法。

如果你不给它任何日期,它将围绕当前时间。在您的情况下,您可以四舍五入到最接近的 15 分钟。

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
很好的答案,包含详细信息、选项和示例!谢谢。
2021-04-03 09:33:38

这里的代码有点冗长,但我相信您会看到如何组合这些行以使其更短。我已经离开它以清楚地显示步骤:

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);
@Lorenz03Tx 有点超出问题的范围,请随时接受我的答案并扩展您自己的答案。
2021-03-18 09:33:38
有一个问题,如果时间是晚上 11:46,它不会更改日期
2021-03-19 09:33:38
这将使秒和毫秒字段不四舍五入。
2021-03-26 09:33:38
上升一个小时时,您将不得不增加一个小时。
2021-04-10 09:33:38
@Robert Koritnik:是的,在我发布后意识到这一点。
2021-04-12 09:33:38

除以 9e5 毫秒(15 * 60 * 1000),四舍五入,再乘以 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) )