也许有人能给我一些好主意,如何做到这一点。
我想获得基于当前日期的一个月的前两周或后两周的工作日。
所以如果我们使用下面的代码来获取今天的日期(2022-07-06)
const current = new Date();
const date = `${current.getFullYear()}-${current.getMonth()+1}-${current.getDate()}`;
我要查找的结果是
const firstHalfWeekdates = ['2022-07-04', '2022-07-05', '2022-07-06', '2022-07-07', '2022-07-08', '2022-07-11', '2022-07-12', '2022-07-13', '2022-07-14', '2022-07-15']
,如果日期落在2022-07-18,它将返回
const secondHalfWeekdates = ['2022-07-18', '2022-07-19', '2022-07-20', '2022-07-21', '2022-07-22', '2022-07-25', '2022-07-26', '2022-07-27', '2022-07-28', '2022-07-29']
也很乐意使用库
也许这可以给你一个开始。它返回工作日除以周。
我试图做你要求的一切,但我遇到了一些问题,例如你想把一个月分成4周,2在上半周和2在下半周,但例如这个月现在7月/2022,有一个星期只有一个工作日(7月1日),但在你的预期结果中你忽略了这一周,忽略周的逻辑是什么?它必须是一个完整的星期,有5个工作日?那么上个月6月/2022,没有4个完整的周,只有3个完整的周,另外2个分别有3天和4天,在这种情况下你会忽略哪个周?
function isWeekDay(day) {
return day != 0 && day != 6;
}
function formatDateYYYYMMDD(date) {
let dateString = date.toLocaleDateString('en-GB');
let year = dateString.substring(6, 10);
let month = dateString.substring(3, 5);
let day = dateString.substring(0, 2);
return `${year}-${month}-${day}`;
}
function getWeekdaysOfTheCurrentMonthDividedByWeek() {
let currentDate = new Date();
let month = currentDate.getMonth();
let weekdays = [];
let tempDate = new Date(currentDate.getFullYear(), currentDate.getMonth(), 1);
let week = [];
while (tempDate.getMonth() == month) {
if (isWeekDay(tempDate.getDay())) {
week.push(formatDateYYYYMMDD(tempDate));
} else if (week.length > 0) {
weekdays.push(week);
week = [];
}
tempDate.setDate(tempDate.getDate() + 1);
}
return weekdays;
}
console.log(getWeekdaysOfTheCurrentMonthDividedByWeek());
您可以将一个月分成日历周。(例如,2022年7月的日期为:7月1-2日、3-9日、10-16日等)
然后,根据具体日期,选择前半周或后半周。
遍历过滤后的周,计算工作日。
如果有5周,我选择包括上半月的第三周,但您可以通过将Math.ceil
更改为Math.floor
来更改
/**
* Get the last item in an array, or undefined if the array is empty.
* @template T
* @param {[T]} array
* @returns {T|undefined}
*/
const lastItem = array => array[array.length - 1];
const getWeekdays = current => {
/** @type {[[Date]]} */
const weeks = [];
// Get the weeks
/**
* Get the calendar week of the given date.
* @param {Date} firstDay The first day of the week.
* @returns {[Date]}
*/
const getWeek = firstDay => {
/** @type {[Date]} */
let days = [];
let dateToTest = new Date(firstDay);
// Continue until the end of the week or month, whichever comes first.
while (
dateToTest.getDay() <= 6 &&
dateToTest.getMonth() == firstDay.getMonth()
) {
days.push(new Date(dateToTest));
dateToTest.setDate(dateToTest.getDate() + 1);
}
return days;
};
// The first day of the month
const firstDay = new Date(current.getFullYear(), current.getMonth());
let dateToTest = new Date(firstDay);
do {
weeks.push(getWeek(dateToTest));
dateToTest = new Date(lastItem(lastItem(weeks)));
dateToTest.setDate(dateToTest.getDate() + 1);
} while (dateToTest.getMonth() == firstDay.getMonth());
// Filter to half of the month
// Get the week of the given date
let currentWeek = 0;
weekLoop: for (let i = 0; i < weeks.length; i++) {
const week = weeks[i];
for (const day of week) {
if (day == current) {
currentWeek = i;
break weekLoop;
}
}
}
/** @type {[[Date]]} */
let weeksInHalf = [];
const numOfWeeksInFirstHalf = Math.ceil(weeks.length / 2),
numOfWeeksInSecondHalf = weeks.length - numOfWeeksInFirstHalf;
for (
let i = 0;
i <
(currentWeek < numOfWeeksInFirstHalf
? numOfWeeksInFirstHalf
: numOfWeeksInSecondHalf);
i++
) {
weeksInHalf.push(weeks[i]);
}
// Filter out weekends
// Format dates
return weeksInHalf
.flat()
.filter(day => day.getDay() > 0 && day.getDay() < 6)
.map(
day => `${day.getFullYear()}-${day.getMonth() + 1}-${day.getDate()}`
);
};
// Tests
for (let i = 0; i < 12; i++) {
const weekdays = getWeekdays(new Date(2022, i));
weekdays.forEach(dateString => {
const [year, month, day] = dateString.split("-");
const date = new Date(year, month - 1, day);
if (date.getDay() == 0 || date.getDay() == 6)
throw new Error("Invalid day: (day)");
else console.log(dateString)
});
}