Moment: 四舍五入到最接近的 15 分钟间隔。

创建于 2013-07-27  ·  18评论  ·  资料来源: moment/moment

我想知道是否有办法向上或向下舍入到最近的 15 分钟间隔。 我认为这将是一个很棒的功能,因为我在搜索时看到的一些库(例如 datejs)具有此功能。 我的情况是,我将数据点分成 15 分钟的时间段,选择工具返回任何时间块,我需要向下舍入到最接近的 15 分钟并向上舍入结束时间。

这样做(http://stackoverflow.com/questions/4968250/how-to-round-time-to-the-nearest-quarter-hour-in-javascript)似乎会很痛苦......当它在 lib 本身中会有用。

最有用的评论

无需复杂,简单的数学:

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 分钟季度。

所有18条评论

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

晚会迟到了,我知道,但是……

@janwerkhovennearestMinutes函数不对; 这意味着它会根据分钟向上或向下取整,因此四舍五入到最接近的 15 我们期望12:34 -> 12:3012: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');

此页面是否有帮助?
0 / 5 - 0 等级

相关问题

benhathaway picture benhathaway  ·  3评论

IbraheemAlSaady picture IbraheemAlSaady  ·  3评论

ninigix picture ninigix  ·  3评论

BCup picture BCup  ·  3评论

Delgan picture Delgan  ·  3评论