我想检查日期是否在一个范围内,但我想忽略年份。
例如:
let data = [{dateFrom: '2021-03-01', dateTo: '2021-04-01', nextYear: false},
{dateFrom: '2021-12-01', dateTo: '2022-01-10', nextYear: true}]; // can't be changed
let today = new Date();
let todaysData = data.filter((x) => {
if(x.nextYear) {
return new Date(x.dateFrom + ' 00:00:00') < today && new Date(x.dateTo + ' 23:59:59') > today
} else {
return new Date(x.dateFrom + ' 00:00:00') < today && new Date(x.dateTo + ' 23:59:59') > today
}
});
如果今天是在 3 月 1 日到 4 月 1 日之间,则第一个数据样本应该为真。
如果今天是在 12 月 1 日到 1 月 10 日之间,则为第二个。
如果年份相同,这有效,但我希望无论年份如何,这个表达式都是正确的。此外,如果范围中有下一年,则设置“nextYear”标志。 (意味着范围是每年的十二月到一月)
我该怎么做?
答案 0 :(得分:1)
如果您创建一个日期进行比较会怎样
有点把它们放在同一年
let today = new Date();
let dateToCompare = new Date(''+ today.getYear()+'-'+
x.dateFrom.getMounth()+'-'+ x.dateFrom.getDay());
我认为这不是最好的选择,但可以工作
答案 1 :(得分:1)
您可以通过将 dateFrom
和 dateTo
值转换为 ISO 8601 日期字符串,然后将它们传递给 Date
构造函数来过滤数据。您甚至不需要使用 nextYear
标志。
更新如果您想为 true
包含 nextYear
的日期,您可以将它们的年份设置为当前年份,如果 dateFrom
超过 dateTo
。
/**
* Filters an array of data objects containing date ranges.<p>
* @param {Object[]} data - an array of objects
* @param {String} data.dateFrom - data start date
* @param {String} data.dateTo - data end date
* @param {Boolean} data.nextYear - if the {@code dateTo} goes into next year
* @param {Date} [date=new Date()] - target date within data's date range
* @return a filtered data array
*/
const filterData = (data, date = new Date()) =>
data.filter(x =>
((startDate, endDate) => {
if (x.nextYear) {
startDate.setFullYear(date.getFullYear());
endDate.setFullYear(date.getFullYear());
if (startDate > endDate) {
let tmp = startDate;
startDate = endDate;
endDate = tmp;
}
}
return date >= startDate && date <= endDate;
})
(new Date(`${x.dateFrom}T00:00:00`), new Date(`${x.dateTo}T23:59:59`)))
const data = [
{ dateFrom: '2021-03-01', dateTo: '2021-04-01', nextYear: false },
{ dateFrom: '2021-12-01', dateTo: '2022-01-10', nextYear: true }
];
console.log(filterData(data));
.as-console-wrapper { top: 0; max-height: 100% !important; }
答案 2 :(得分:1)
在非常仔细地阅读 OP 的验收标准后,一种方法是编写例如一个 getYearLeveledTime
辅助函数,它将每个日期格式字符串值规范化为日期时间数字值。无论传递的日期格式如何,此日期时间的全年基数都调整到 1970 年。仅考虑这种格式的月份和日期。一个额外的标志将时间值增加一整年的定时量。并且为了在任何情况下都保持在保存端,另一个像 getSanitizedTimeRange
这样的小助手会处理正确的范围值优先级。
完成上述设置后,编写过滤函数就容易多了,只需查看某个时间值是否在时间范围内即可。该任务实际上归结为... (time >= timeFrom) && (time <= timeTo)
的返回值。
function getSanitizedTimeRange(a, b) {
return ((a < b) && [a, b]) || [b, a];
}
function getYearLeveledTime(date, isAddOneYear) {
date = (date && new Date(date)) || new Date();
const baseDate = new Date(0);
baseDate.setDate(date.getDate());
baseDate.setMonth(date.getMonth());
if (isAddOneYear) {
baseDate.setFullYear(baseDate.getFullYear() + 1);
}
return baseDate.getTime();
}
function isBoundTimeWithinYearAgnosticRange(dateItem) {
const [
timeFrom,
timeTo,
] = getSanitizedTimeRange(
getYearLeveledTime(dateItem.dateFrom),
getYearLeveledTime(dateItem.dateTo, dateItem.nextYear)
);
const { time } = this; // bound time.
// whether time is within range or not.
return (time >= timeFrom) && (time <= timeTo);
}
const data = [
{dateFrom: '2021-03-01', dateTo: '2021-04-01', nextYear: false},
{dateFrom: '2021-12-01', dateTo: '2022-01-10', nextYear: true},
];
console.log(
'filtered, year agnostic, time ranges ...',
data.filter(isBoundTimeWithinYearAgnosticRange, { time: getYearLeveledTime() })
);
console.log(
"today's base time ... new Date(getYearLeveledTime()) ...",
new Date(getYearLeveledTime()),
`(${ getYearLeveledTime() })`
);
console.log(
'new Date(getYearLeveledTime("2021-12-01")) ...',
new Date(getYearLeveledTime("2021-12-01")),
`(${ getYearLeveledTime("2021-12-01") })`
);
console.log(
'new Date(getYearLeveledTime("2022-01-10", true)) ...',
new Date(getYearLeveledTime("2022-01-10", true)),
`(${ getYearLeveledTime("2022-01-10", true) })`
);
.as-console-wrapper { min-height: 100%!important; top: 0; }