我想知道是否有办法向上或向下舍入到最近的 15 分钟间隔。 我认为这将是一个很棒的功能,因为我在搜索时看到的一些库(例如 datejs)具有此功能。 我的情况是,我将数据点分成 15 分钟的时间段,选择工具返回任何时间块,我需要向下舍入到最接近的 15 分钟并向上舍入结束时间。
这样做(http://stackoverflow.com/questions/4968250/how-to-round-time-to-the-nearest-quarter-hour-in-javascript)似乎会很痛苦......当它在 lib 本身中会有用。
moment.fn.roundMinutes = function () { return ~(this.minutes() / 15) * 15; }
我创建了这个供我自己使用,并认为它可以帮助其他人。 请记住,它会四舍五入到最近的 NEXT 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);
能否请您将这些函数添加到 moment.. 能够四舍五入到最近的、下一个和上一个时间间隔真是太棒了...有数百万个谷歌搜索结果和数百个堆栈溢出赞成票..
现在我再次查看它,我不知道 incrementHours 是如何工作的。
我已经用更正的代码编辑了我的帖子。 享受!
2014 年 3 月 10 日星期一下午 2:29,Blake Niemyjski
通知@github.com写道:
你的 incrementHours 函数是什么? 我猜这也做了几天
也。直接回复本邮件或在Gi tHub上查看
.
感谢这种方法@zbarnett 。 正是我的项目所需要的
好吧,我们可以像这样startOf(15, 'm')
使用 startOf 接口。 它适用于所有单位。 等待 PR :)
这是一个非常简单的公式(在 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);
在代码笔上测试
关键是做.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"))
晚会迟到了,我知道,但是……
@janwerkhoven的nearestMinutes
函数不对; 这意味着它会根据分钟向上或向下取整,因此四舍五入到最接近的 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
克服了这个问题
@凯夫拉尔
Math.round(39/15)
返回 3 而不是 2。
Math.round(39/15) * 15
返回 45 而不是 30。
哈哈,这就是我在一天结束时没有睡觉的时候阅读太多线程而得到的。我在做Math.floor
我喜欢_zbarnett 解决方案_! 便于使用
函数 _ this.milliseconds(0) 的小更新
var newdate=turno.date.clone().roundNext15Min().add(anticipation, 'minutes');
moment.fn.roundNext15Min = 函数 () {
var 间隔 = Math.floor(this.minutes() / 15);
if(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 分钟季度。