我有一个日期范围
示例日期范围:
const startDate = "2022-06-02";
const endDate = "2022-06-20";
我想得到那些日期,这些日期出现在提供的日期数组中,该数组位于startDate&结束日期
天数数组示例:
["tuesday", "friday", "saturday"]
预期结果是:
2022-06-03
2022-06-04
2022-06-07
2022-06-10
2022-06-11
2022-06-14
2022-06-17
2022-06-18
有人能帮我理解这个逻辑吗?
What I tried was so dirty, I put a loop on range of dates, and got the list of all dates, and then i put another loop to get name of day of each date, and then compared each day name in an array of days & pushed that date to new array
这是代码(工作非常好)但我需要更好的解决方案:
function getDaysArray(start, end) {
for(var arr=[],dt=new Date(start); dt<=new Date(end); dt.setDate(dt.getDate()+1)){
arr.push(helperClass.getDateTime(new Date(dt)).date);
}
return arr;
}
function getDayName (dateStr, locale){
var date = new Date(dateStr);
return date.toLocaleDateString(locale, { weekday: 'long' });
}
var days = ["tuesday", "friday", "saturday"];
var getAllDates = getDaysArray("2022-06-02", "2022-06-20");
var getDates = [];
for(var i = 0; i < getAllDates.length; i++){
if(days.includes(getDayName(getAllDates[i]).toLowerCase())){
getDates.push(getAllDates[i])
}
}
如果您可以使用外部库,则date-fns库为此提供了一些帮助:
parse
-返回使用给定格式字符串从字符串解析的日期eachDayOfInterval
-返回指定时间间隔内的日期数组getDay
-获取给定日期的星期几- 或
is*
助手,例如isSunday
、isMonday
等
因此,如果你分析你的开始和结束日期,得到一个完整的间隔范围,然后根据日期进行筛选,你就会有你的列表。
import("https://unpkg.com/date-fns@2.28.0/esm/index.js").then(({ eachDayOfInterval, getDay, parse }) => {
const startDate = parse("2022-06-02", "yyyy-MM-dd", new Date());
const endDate = parse("2022-06-20", "yyyy-MM-dd", new Date());
const daysOfWeek = ["sunday", "monday", "tuesday", "wednesday", "thursday", "friday", "saturday"];
// Here is your list
const daysToFilterFor = ["tuesday", "friday", "saturday"];
const daysToFilterForIndex = daysToFilterFor.map((day) => daysOfWeek.indexOf(day));
const range = eachDayOfInterval({
start: startDate,
end: endDate,
}).filter((day) => daysToFilterForIndex.includes(getDay(day)));
console.log(range);
});
示例中对详细信息进行了注释
// Array of days to filter
const daysOff = ["Tuesday", "Friday", "Saturday"];
/**
* @desc Determine the specific dates of days that match a given array
* of weekdays within the range of two given dates.
* @param {string<date>} start - The first date of the range
* @param {string<date>} end - The last date of the range
* @param {array<string>} weekdays - The list of days used to find the dates
* @return {array<date>} An array of dates that correspond to weekdays
*/
function dateRanger(start, end, weekdays) {
// Convert dates into timestamps {number}
const A = Date.parse(start);
const Z = Date.parse(end);
// Seconds in a day
const day = 86400000;
// Determine number of days the range spans
const total = Math.floor(((Z - A) / day) + 1);
// Object that stores format settings for .toLocaleDateString()
const options = {
weekday: 'long',
year: 'numeric',
month: 'numeric',
day: 'numeric'
};
/*
- Instantiate an Array with room to fit the range of dates
- On each iteration instantiate a date based on the first date then format
it and add it's weekday using .toLocaleDateString()
- Return date string as an array of pairs using .split()
*/
const range = [...new Array(total)].map(
(_, i) => new Date(A + (day * i))
.toLocaleDateString('en-US', options)
.split(', ')
);
/*
- .flatMap() the first level of range to access the array of pairs
- On each iteration compare the first value of each pair (sub[0]) with the
given array (weekdays).
- If there's a match, return the second value (sub[1]) of each pair
- Otherwise return an empty array that gets flattened to zilch.
*/
return range.flatMap(
sub => weekdays.flatMap(
day => day === sub[0] ?
sub[1] : []
)
);
}
console.log(dateRanger('6-4-2022', '6-20-2022', daysOff));
我知道这可能不是最好的方法,但下面是我如何做到的
let days = { monday: 0, tuesday: 1, wednesday: 2, thursday: 3, friday: 4, saturday: 5, sunday: 6 };
const startDate = "2022-06-02";
const endDate = "2022-06-20";
function daysindates(arr) {
let stdate = startDate.substr(-2);
let endate = endDate.substr(-2);
let myarr = [],
result = [],
finalresult = [];
for (y of arr) {
for (let i = parseInt(stdate) + days[y]; i <= parseInt(endate); i += 7) {
result.push(i);
}
}
finalresult = result.map((item) => {
return "2022-06-" + item;
});
console.log(finalresult);
}
daysindates(["monday", "tuesday"]);