私は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は正しい日付を記録していますが、配列には最終日付のみが追加されています。これはなぜですか?これは、ある種の変数参照の問題のような匂いがします-しかし、私はそれを見ていません。
.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;
};
_
あなたのためにそれを得た:
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
Momentjsはそれ自体を提供しませんが、それを提供するプラグインがあります: moment-range
。
具体的には、 Iteration docs を確認してください。
カイルの答えの延長として-私はこれを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']
moment.js
を使用して簡単に列挙できます。日、週、月、または年のより一般的なソリューションを次に示します。
https://Gist.github.com/gvko/76f0d7b4b61b18fabfe9c0cc24fc3d2a