我有两个时刻日期:
var fromDate = moment(new Date('1/1/2014'));
var toDate = moment(new Date('6/1/2014'));
moment 是否提供了枚举这两个日期之间的所有日期的方法?
如果没有,除了创建一个将
fromDate
加 1 直到达到 toDate
的循环之外,是否还有更好的解决方案?
编辑:添加日期枚举方法和问题
我已经模拟了一种枚举两个日期之间的天数的方法,但我遇到了一个问题。
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()
是一个 mutator 方法,因此这一行中的赋值是不必要的:
startDate = startDate.add(1, 'days');
你可以这样做,并获得相同的效果:
startDate.add(1, 'days');
虽然它的名称意味着创建一个新的
Date
对象,但 toDate()
方法实际上只是返回现有的内部 Date
对象。
因此,您的方法调用都不会创建新的
Date
或 moment
对象实例。通过使用 .clone()
获取新实例来修复此问题:
startDate = startDate.clone().add(1, 'days');
或者更好的是,将值包装在对
moment()
的调用中,如 Mtz 在注释中建议的那样,如果该值是一个 moment 对象,它将克隆实例,或者它将解析输入以创建一个新的 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
使用 moment 并使用 while 循环,代码将循环运行,直到 startDate 等于 endDate 并推送 startDate,然后将其增加 1 天,以便获得下一个日期
function enumerateDaysBetweenDates (startDate, endDate){
let date = []
while(moment(startDate) <= moment(endDate)){
date.push(startDate);
startDate = moment(startDate).add(1, 'days').format("YYYY-MM-DD");
}
return date;
}
你可以通过调用这样的函数来测试它
let dateArr = enumerateDaysBetweenDates('2019-01-01', '2019-01-10');
使用
moment library
和 for loop
您可以枚举两个日期之间的值。
let startDate = moment('2020-06-21');
let endDate = moment('2020-07-15');
let date = [];
for (var m = moment(startDate); m.isBefore(endDate); m.add(1, 'days')) {
date.push(m.format('YYYY-MM-DD'));
}
console.log(date)
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.min.js"></script>
作为凯尔答案的扩展 - 我一直在尝试让它与 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']
使用ES6表示法
const from = moment('01/01/2014', 'DD/MM/YYYY')
const to = moment('06/01/2014', 'DD/MM/YYYY')
const nbDays = to.diff(from, 'days') + 1
const result = [...Array(nbDays).keys()]
.map(i => from.clone().add(i, 'd'))
console.log(result)
<script src="https://momentjs.com/downloads/moment.min.js"></script>
您可以使用
moment.js
轻松枚举,这是针对天、周、月或年的更通用解决方案:
https://gist.github.com/gvko/76f0d7b4b61b18fabfe9c0cc24fc3d2a
使用矩库和 for 循环,您可以枚举两个日期之间的值。
const moment = require('moment');
let startDate = moment('2021-12-24');
let endDate = moment('2022-1-4');
let date = [];
for (var m = moment(startDate); m.isSameOrBefore(endDate); m.add(1, 'days')) {
date.push(m.format('DD/MM/YYYY'));
}
console.log(date)
使用递归的简短解决方案
import type { Moment } from 'moment';
export const getDatesBetween = (start: Moment, end: Moment): Moment[] => {
if (!start.isValid() || !end.isValid() || start.isAfter(end, 'day')) return [];
if (start.isSame(end, 'day')) return [start];
return [start].concat(getDatesBetween(start.clone().add(1, 'day'), end));
};