Мне было интересно, есть ли у меня способ округлить до ближайшего 15-минутного интервала вверх или вниз. Я думаю, что это было бы отличной функцией, поскольку некоторые библиотеки, такие как datejs, имеют такую функциональность из того, что я видел при поиске. Мой сценарий состоит в том, что у меня есть точки данных, которые сегментированы на 15-минутные сегменты. Инструмент выбора возвращает любой блок времени, и мне нужно округлить до ближайших 15 минут и округлить до конечного времени.
Делать это таким образом (http://stackoverflow.com/questions/4968250/how-to-round-time-to-the-nearest-quarter-hour-in-javascript) кажется болью .. когда это было бы полезно иметь в самой библиотеке.
moment.fn.roundMinutes = function () { return ~(this.minutes() / 15) * 15; }
Я создал это для себя и решил, что это может помочь другим. Имейте в виду, что округляется до ближайших СЛЕДУЮЩИХ 15 мин.
moment.fn.roundNext15Min = function () {
var intervals = Math.floor(this.minutes() / 15);
if(this.minutes() % 15 != 0)
intervals++;
if(intervals == 4) {
this.add('hours', 1);
intervals = 0;
}
this.minutes(intervals * 15);
this.seconds(0);
return this;
}
РЕДАКТИРОВАТЬ: удалили this.incrementHours () в пользу this.add ('hours', 1);
Не могли бы вы добавить эти функции к моменту ... Было бы здорово иметь возможность округлять до ближайшего, следующего и предыдущего временных интервалов ... Для этого есть миллионы результатов Google и сотни голосов за переполнение стека ..
Теперь, когда я смотрю на это снова, я понятия не имею, как работал incrementHours.
Я отредактировал свой пост к проблеме с исправленным кодом. Наслаждаться!
В пн, 10 марта 2014 г., в 14:29, Блейк Немийски
[email protected] написал :
Какова была ваша функция для incrementHours? Я предполагаю, что и дни
тоже.Ответьте на это письмо напрямую или просмотрите его на Gi tHubhttps: //github.com/moment/moment/issues/959#issuecomment -37223821
.
спасибо за этот метод @zbarnett . Именно то, что мне нужно для моего проекта
Что ж, мы можем использовать интерфейс startOf как этот startOf(15, 'm')
. Он может работать для всех юнитов. Жду пиаров :)
Вот довольно простая формула (в синтаксисе Coffeescript, поскольку именно в этом контексте я столкнулся с этой проблемой):
round_interval = 15
remainder = time.minute() % round_interval
time.subtract('minutes', remainder).add('minutes', if remainder > round_interval / 2 then round_interval else 0)
Я сейчас достаточно занят другими вещами, но если кто-то хочет взять этот код и поместить его прямо в PR, не стесняйтесь.
Закрытие в пользу №1595
Не нужно усложнять, простая математика:
const rounded = Math.round(moment().minute() / 15) * 15;
const roundedDown = Math.floor(moment().minute() / 15) * 15;
const roundedUp = Math.ceil(moment().minute() / 15) * 15;
moment().minute(roundedUp).second(0)
Выводит до ближайшего 15-минутного квартала.
Мне не удалось заставить решение @janwerkhoven работать, поэтому вот мое:
function round15(minute) {
let intervals = [15, 30, 45, 59, 0];
let closest;
let min = 90;
for (let i = 0; i < intervals.length; i++) {
let iv = intervals[i];
let maybeMin = Math.abs(minute - iv);
if (maybeMin < min) {
min = maybeMin;
closest = iv;
}
}
if (closest === 59) {
closest = 0;
}
return closest;
}
let myMoment = moment();
myMoment.minutes(round15(myMoment.minutes()));
@ Ground5hark
function nearestMinutes(interval, someMoment){
const roundedMinutes = Math.round(someMoment.clone().minute() / interval) * interval;
return someMoment.clone().minute(roundedMinutes).second(0);
}
function nearestPastMinutes(interval, someMoment){
const roundedMinutes = Math.floor(someMoment.minute() / interval) * interval;
return someMoment.clone().minute(roundedMinutes).second(0);
}
function nearestFutureMinutes(interval, someMoment){
const roundedMinutes = Math.ceil(someMoment.minute() / interval) * interval;
return someMoment.clone().minute(roundedMinutes).second(0);
}
const now = moment();
const nearest5min = nearestMinutes(5, now);
const nearest15min = nearestMinutes(15, now);
const nearest30min = nearestMinutes(30, now);
const nearestFuture5min = nearestFutureMinutes(5, now);
const nearestPast5min = nearestPastMinutes(5, now);
Протестировано на Code Pen
Решающим моментом является выполнение .clone()
. Без него вы бы редактировали исходный moment()
что часто бывает при использовании Moment.js.
Попробуйте, ребята
time = moment("01:46", "HH:mm");
round_interval = 30;//15;
intervals = Math.floor(time.minutes() / round_interval);
minutesToRound = time.minutes() % round_interval;
minutesRounded = minutesToRound>round_interval/2 ? round_interval: 0;
minutes = intervals * round_interval + minutesRounded;
time.minutes(minutes);
alert(time.format("HH:mm"))
Поздно на вечеринку, я знаю, но ...
Функция nearestMinutes
@janwerkhoven неверна ; это означает, что он будет округляться в большую или меньшую сторону в зависимости от минуты, поэтому, округляя до ближайших 15, мы ожидаем 12:34 -> 12:30
и 12:39 -> 12:45
const roundedMinutes = Math.round(someMoment.clone().minute() / interval) * interval;
// 12:34 is fine...
// => Math.round(34 / 15) * 15
// => 2 * 15
30
// ... but 12:39 is not - it should be 45
// => Math.round(39 / 15) * 15
// => 2 * 15
30
Решение @Silviusconcept преодолевает это с помощью minutesRounded
@kevlarr
Math.round(39/15)
возвращает 3, а не 2.
Math.round(39/15) * 15
возвращает 45, а не 30.
Ха-ха, вот что я получаю, прочитав слишком много обсуждений в конце дня, когда не спал ... Я делал Math.floor
Мне нравится _zbarnett solution_ ! Легко использовать
Небольшое обновление функции _ this.milliseconds (0); _
var newdate = turno.date.clone (). roundNext15Min (). add (ожидание, 'минуты');
moment.fn.roundNext15Min = function () {
интервалы var = Math.floor (this.minutes () / 15);
если (this.minutes ()% 15! = 0)
интервалы ++;
если (интервалы == 4) {
this.add ('часы', 1);
интервалы = 0;
}
this.minutes (интервалы * 15);
this.seconds (0);
_ this.milliseconds (0); _
вернуть это;
}
Моя версия ответа
const startOf = (m, n, unit) => {
const units = [
'year',
'month',
'hour',
'minute',
'second',
'millisecond',
];
const pos = units.indexOf(unit);
if (pos === -1) {
throw new Error('Unsupported unit');
}
for (let i = pos + 1; i < units.length; i++) {
m.set(units[i], 0);
}
m.set(unit, Math.floor(m.get(unit) / n) * n);
return m;
};
const endOf = (m, n, unit) => {
const units = [
'year',
'month',
'hour',
'minute',
'second',
'millisecond',
];
const pos = units.indexOf(unit);
if (pos === -1) {
throw new Error('Unsupported unit');
}
for (let i = pos + 1; i < units.length; i++) {
m.set(units[i], units[i] === 'millisecond' ? 999 : 59);
}
m.set(unit, Math.floor(m.get(unit) / n) * n + n - 1);
return m;
};
Используйте так:
startOf(moment(), 15, 'minute');
endOf(moment(), 15, 'minute')
// with moment-timezone
startOf(moment().tz("Europe/London"), 15, 'minute');
Эти функции изменят исходный объект, при необходимости используйте clone()
другое решение:
let next15Minutes = moment().add(15, 'minutes');
next15Minutes.minutes(Math.floor(next15Minutes.minutes() / 15) * 15);
next15Minutes.format('HH:mm');
Самый полезный комментарий
Не нужно усложнять, простая математика:
Выводит до ближайшего 15-минутного квартала.