web-dev-qa-db-ja.com

Momentの2つの日付間の日付を列挙する方法

私は2つの モーメント 日付を持っています:

_var fromDate = moment(new Date('1/1/2014'));
var toDate   = moment(new Date('6/1/2014'));
_

モーメントは、これら2つの日付間のすべての日付を列挙する方法を提供しますか?

そうでない場合、fromDateに到達するまでtoDateを1ずつ増分するループを作成する以外のより良い解決策はありますか?

編集:日付列挙方法と問題の追加

2つの日付の間の日を列挙する方法をモックアップしましたが、問題に直面しています。

_  var enumerateDaysBetweenDates = function(startDate, endDate) {
    var dates = [];

    startDate = startDate.add(1, 'days');

    while(startDate.format('M/D/YYYY') !== endDate.format('M/D/YYYY')) {
      console.log(startDate.toDate());
      dates.Push(startDate.toDate());
      startDate = startDate.add(1, 'days');
    }

    return dates;
  };
_

enumerateDaysBetweenDates( moment(new Date('1/1/2014')), moment(new Date('1/5/2014'));を実行したときの出力を見てください

_Thu Jan 02 2014 00:00:00 GMT-0800 (PST)
Fri Jan 03 2014 00:00:00 GMT-0800 (PST)
Sat Jan 04 2014 00:00:00 GMT-0800 (PST)
[ Sun Jan 05 2014 00:00:00 GMT-0800 (PST),
  Sun Jan 05 2014 00:00:00 GMT-0800 (PST),
  Sun Jan 05 2014 00:00:00 GMT-0800 (PST) ]
_

Console.loggingは正しい日付を記録していますが、配列には最終日付のみが追加されています。これはなぜですか?これは、ある種の変数参照の問題のような匂いがします-しかし、私はそれを見ていません。

40
doremi

.add() はミューテーターメソッドであるため、この行の割り当ては不要です。

_startDate = startDate.add(1, 'days');
_

これを行うだけで、同じ効果が得られます。

_startDate.add(1, 'days');
_

名前は新しいDateオブジェクトの作成を意味しますが、 toDate() メソッドは実際には既存の内部Dateオブジェクトを返します。

したがって、どのメソッド呼び出しも新しいDateまたはmomentオブジェクトインスタンスを作成していません。 .clone() を使用して新しいインスタンスを取得することで修正します。

_startDate = startDate.clone().add(1, 'days');
_

または、より良いことに、コメントで Mtz が示唆するように、moment()の呼び出しで値をラップし、値が瞬間オブジェクトである場合、インスタンスを複製します。入力を解析して、新しいモーメントインスタンスを作成します。

_startDate = moment(startDate).add(1, 'days');
_

日付列挙子メソッドは、渡された引数のいずれも変更すべきではないと思います。列挙のために別の変数を作成します。また、文字列を比較するのではなく、日付を直接比較します。

_var enumerateDaysBetweenDates = function(startDate, endDate) {
    var dates = [];

    var currDate = moment(startDate).startOf('day');
    var lastDate = moment(endDate).startOf('day');

    while(currDate.add(1, 'days').diff(lastDate) < 0) {
        console.log(currDate.toDate());
        dates.Push(currDate.clone().toDate());
    }

    return dates;
};
_
72
gilly3

あなたのためにそれを得た:

var enumerateDaysBetweenDates = function(startDate, endDate) {
    var now = startDate.clone(), dates = [];

    while (now.isSameOrBefore(endDate)) {
        dates.Push(now.format('M/D/YYYY'));
        now.add(1, 'days');
    }
    return dates;
};

nowではなくstartDateを参照すると、すべての違いが生じます。

包括的検索を行っていない場合は、.isSameOrBeforeから.isBefore

フィドル:http://jsfiddle.net/KyleMuir/sRE76/118/

33
Kyle Muir

Momentjsはそれ自体を提供しませんが、それを提供するプラグインがあります: moment-range

具体的には、 Iteration docs を確認してください。

4
Cody Caughlan

カイルの答えの延長として-私はこれをUnixタイムスタンプで動作させようとしましたが、多くの試行錯誤の後、私はそれを動作させ、誰かが同じものとニーズを求めている場合にここに投稿すると思いましたそれ。以下の私のコードを参照してください:

fromDate = moment.unix(req.params.dateFrom).format('YYYY-MM-DD')
toDate = moment.unix(req.params.dateTo).format('YYYY-MM-DD')

// Returns an array of dates between the two dates
function enumerateDaysBetweenDates(startDate, endDate) {
    startDate = moment(startDate);
    endDate = moment(endDate);

    var now = startDate, dates = [];

    while (now.isBefore(endDate) || now.isSame(endDate)) {
        dates.Push(now.format('YYYY-MM-DD'));
        now.add(1, 'days');
    }
    return dates;
};

これをUnixに変換してから、その値を再び瞬間に変換することに注意してください。これは私が抱えていた問題でした。これを機能させるためには、再びモーメント値にする必要があります。

使用例:

fromDate = '2017/03/11' // AFTER conversion from Unix
toDate = '2017/03/13' // AFTER conversion from Unix

console.log(enumerateDaysBetweenDates(fromDate, toDate));

戻ります:

['2017/03/11', '2017/03/12', '2017/03/13']
1
jock.perkins

moment.jsを使用して簡単に列挙できます。日、週、月、または年のより一般的なソリューションを次に示します。

https://Gist.github.com/gvko/76f0d7b4b61b18fabfe9c0cc24fc3d2a

1
Milkncookiez