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自体に含めると便利です。

todo

最も参考になるコメント

複雑で単純な計算をする必要はありません。

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

私はこれを自分で使用するために作成し、他の人に役立つかもしれないと考えました。 最も近い次の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.add( 'hours'、1);を優先してthis.incrementHours()を削除しました。

これらの関数を瞬間に追加していただけませんか。最も近い、次の、および前の時間間隔に丸めることができるのは本当に素晴らしいことです...これに対する数百万のグーグル結果と数百のスタックオーバーフロー賛成票があります。

もう一度見てみると、incrementHoursがどのように機能していたのかわかりません。
修正されたコードで問題の投稿を編集しました。 楽しみ!

2014年3月10日月曜日午後2時29分、Blake Niemyjski
[email protected]

incrementalHoursの関数は何でしたか? 私はそれも何日もしたと思います
それも。

このメールに直接返信するか、Gi tHubhttps://github.com/moment/moment/issues/959#issuecomment-37223821で表示してください

そのメソッド@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.jsを使用する際の一般的な落とし穴である元のmoment()を編集することになります。

この人を試してみてください

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: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)は2ではなく3を返します。
Math.round(39/15) * 15は30ではなく45を返します。

ははは、私が眠っていない一日の終わりにあまりにも多くのスレッドを読んだことで私が得るものです..私はMath.floorやっていた

私は_zbarnettソリューション_が好き
関数の更新はほとんどありません_this.milliseconds(0); _

var newdate = turno.date.clone()。roundNext15Min()。add(anticipation、 'minutes');

moment.fn.roundNext15Min = function(){
var interval = Math.floor(this.minutes()/ 15);
if(this.minutes()%15!= 0)
間隔++;
if(intervals == 4){
this.add( 'hours'、1);
間隔= 0;
}
this.minutes(intervals * 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 評価