Например:
Given time: 08:22 => Rounded to: 08:15
Given time: 08:23 => Rounded to: 08:30
Должно быть довольно просто. Но все, что мне удалось произвести, - это длинный, не очень хороший код для решения проблемы. Мой разум просто пропал.
Привет
Например:
Given time: 08:22 => Rounded to: 08:15
Given time: 08:23 => Rounded to: 08:30
Должно быть довольно просто. Но все, что мне удалось произвести, - это длинный, не очень хороший код для решения проблемы. Мой разум просто пропал.
Привет
Учитывая, что у вас есть часы и минуты в переменных (если вы этого не сделаете, вы можете получить их из экземпляра 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).
// ----
Эта функция округляет время до ближайшей четверти часа.
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;
}
Вот метод, который округляет временную строку, подобную той, которую вы представили. Например, "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
Код здесь немного подробный, но я уверен, вы увидите, как вы могли бы комбинировать линии, чтобы сделать это короче. Я оставил его таким образом, чтобы четко показать шаги:
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);
Разделите на 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) )
Существует пакет 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)
Затем вы можете использовать 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
Еще один с 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);
Может помочь другим. Для любого языка. В основном трюк с круглой функцией.
roundedMinutes = yourRoundFun(Minutes / interval) * interval
например. Интервал может составлять 5 минут, 10 минут, 15 минут, 30 минут. Тогда округленные минуты могут быть reset до соответствующей даты.
yourDateObj.setMinutes(0)
yourDateObj.setMinutes(roundedMinutes)
также при необходимости
yourDateObj.setSeconds(0)
yourDateObj.setMilliSeconds(0)
Simple?