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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4968250/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 15:00:44  来源:igfitidea点击:

How to round time to the nearest quarter hour in JavaScript?

javascripttime

提问by devployment

For example:

例如:

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

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

Should be pretty simple. But all I was able to produce is lengthy, not very good code to solve the issue. My mind's just gone blank.

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

Regards

问候

回答by Robert Koritnik

Given that you have hours and minutes in variables (if you don't you can get them from the Dateinstance anyway by using Dateinstance functions):

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

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

minutes can as well be calculated by using Math.round():

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

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

or doing it in a more javascript-sophisticated expression without any functions:

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

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

You can check the jsPerf test that shows Math.round()is the slowest of the three while mainly the last one being the fastest as it's just an expression without any function calls (no function call overhead i.e. stack manipulation, although native functions may be treated differently in Javascript VM). //----

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

回答by Antoine Desbois

This function round the time to the nearest quarter hour.

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

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

回答by joshuakcockrell

With Time String

带时间字符串

Here is a method that will round a time string like the one you presented. Eg "08:22"

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

With Hours and Minutes Already Split Up

小时和分钟已经分开

You can use this method if you don't need to parse out the hour and minute strings like your example shows

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

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}

With Existing Date Object

使用现有日期对象

Or, if you are looking to round an already existing date object to the nearest x minutes, you can use this method.

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

If you don't give it any date it will round the current time. In your case, you can round to the nearest 15 minutes.

如果你不给它任何日期,它将围绕当前时间。在您的情况下,您可以四舍五入到最接近的 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

回答by Lazarus

The code here is a little verbose but I'm sure you'll see how you could combine the lines to make this shorter. I've left it this way to clearly show the steps:

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

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

回答by Slai

Divide by 9e5 milliseconds (15 * 60 * 1000), round, and multiply back by 9e5 :

除以 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) )

回答by Raja Sekar

Another one with date-fns (not mandatory)

另一个带有 date-fns 的(非强制性)

import {getMinutes, setMinutes, setSeconds, setMilliseconds} from 'date-fns'

let date = new Date();
let min = getMinutes(date);
let interval = 3  // in minutes
let new_min = min - min%interval + interval;
let new_date = setMilliseconds(setSeconds(setMinutes(date,new_min),0),0)

console.log('Orignal Date : ' + date);
console.log('Original Minute : ' + min);
console.log('New Minute : ' + new_min);
console.log('New Date : ' + new_date);

回答by Shubham Rai

Pass the interval in milliseconds get the next cycle in roundUp order

以毫秒为单位传递间隔以roundUp顺序获取下一个周期

Example if I want next 15 minute cycle from current time then call this method like *calculateNextCycle(15 * 60 * 1000);*

例如,如果我想从当前时间开始下一个 15 分钟的周期,然后调用此方法,例如 *calculateNextCycle(15 * 60 * 1000);*

Samething for quarter hour pass the interval

四分之一小时的相同时间通过间隔

function calculateNextCycle(interval) {
    const timeStampCurrentOrOldDate = Date.now();
    const timeStampStartOfDay = new Date().setHours(0, 0, 0, 0);
    const timeDiff = timeStampCurrentOrOldDate - timeStampStartOfDay;
    const mod = Math.ceil(timeDiff / interval);
    return new Date(timeStampStartOfDay + (mod * interval));
}

console.log(calculateNextCycle(15 * 60 * 1000));

回答by Danny Hurlburt

There is an NPM package@qc/date-roundthat can be used. Given that you have a Dateinstance to be rounded

有一个可以使用的NPM 包@qc/date-round。鉴于您有一个Date要舍入的实例

import { round } from '@qc/date-round'

const dateIn = ...; // The date to be rounded
const interval = 15 * 60 * 1000; // 15 minutes (aka quarter hour)
const dateOut = round(dateIn, interval)

Then you can use date-fnsto format the date

然后你可以使用date-fns格式化日期

import format from 'date-fns/format';

console.log(format(dateOut, 'HH:mm')) // 24-hr
console.log(format(dateOut, 'hh:mm a')) // 12-hr

回答by Sai

Might help others. For any language. Mainly trick with round function.

可能会帮助别人。对于任何语言。主要是圆函数的技巧。

roundedMinutes = yourRoundFun(Minutes / interval) * interval

E.g. The interval could be 5 minutes, 10 minutes, 15 minutes, 30 minutes. Then rounded minutes can be reset to the respective date.

例如,间隔可以是 5 分钟、10 分钟、15 分钟、30 分钟。然后可以将四舍五入的分钟重置为相应的日期。

yourDateObj.setMinutes(0) 
yourDateObj.setMinutes(roundedMinutes)

also if required then

如果需要的话

yourDateObj.setSeconds(0) 
yourDateObj.setMilliSeconds(0) 

Simple?

简单的?