perhaps someone can give me some good ideas of how to accomplish this.
I would like to get the weekdays for either the first two weeks or last two weeks of a month based on the current date.
So if we are using the following to get the date today (2022-07-06)
const current = new Date();
const date = `${current.getFullYear()}-${current.getMonth() 1}-${current.getDate()}`;
The results I would be looking for are
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']
and if the date fell on 2022-07-18 it would return
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']
Also happy to use a library
CodePudding user response:
Maybe this can give you a start. It returns the weekdays, divided by week.
I was trying to do everything you asked, but I ran into some problems, for example you want to divide the month into 4 weeks, 2 in the first half and 2 in the second half, but for example this month now July/2022, has a week that has only one weekday (July 1º), but in your expected results you ignored this week, whats the logic to ignore weeks? It has to be a complete week with 5 weekdays? What about last month Jun/2022, there were not 4 complete weeks, there were only 3 complete weeks, the other 2 has 3 and 4 days respectively, which week would you ignore in this case?
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());
CodePudding user response:
You could split the month up into calendar weeks. (e.g. for July 2022 it would be: July 1-2, 3-9, 10-16, ect…)
Then, depending on the day, take either the first or second half of the weeks.
Iterate over the filtered weeks, counting the weekdays.
I choose to include the third week in the first half of the month if there were 5 weeks, but you could change that by changing Math.ceil
to 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)
});
}