Given a period of time, how can i find the date of the first monday and the last friday in that period of time in JavaScript.
Example :
- the period of time : from 28/01/2023 to 21/02/2023.
- given dates : ['MON', "FRI"].
- expectation : return the date of the first day found from the given dates and the date of the last day found from the given dates.
I would like to make the following :
const startDate = "28/01/2023";
const endDate = "21/02/2023";
const days = ['MON', "FRI"];
const findDate = (startDate , endDate, days) => {
return date
}
in this example : the function returns 30/01/2023 (monday) and 20/02/2023 (monday).
another example :
- the period of time : 28/01/2023 - 25/02/2023
- returns : 30/01/2023 (monday) and 24/02/2023 (friday)
another example :
- the period of time : 31/01/2023 - 25/02/2023
- returns : 3/02/2023 (friday) and 24/02/2023 (friday)
Thank you
CodePudding user response:
This is the most imperative approach:
const allDays = ["MON", "TUE", "WED", "THU", "FRI", "SAT", "SUN"];
const startDate = "28/01/2023";
const endDate = "26/02/2023";
function convertToDate(dateString) {
// Convert a "dd/MM/yyyy" string into a Date object
let d = dateString.split("/");
let dat = new Date(d[2] '/' d[1] '/' d[0]);
return dat;
}
function findDate (day, startDate, endDate) {
const dayToJSDay = {
1: "MON",
2: "TUE",
3: "WED",
4: "THU",
5: "FRI",
6: "SAT",
7: "SUN",
};
const d = convertToDate(startDate);
const e = convertToDate(endDate);
while (d.getTime() !== e.getTime()) {
if (dayToJSDay[d.getDay()] === day) {
return d;
}
d.setDate(d.getDate() 1);
}
return null;
};
const a = findDate("MON", startDate, endDate);
console.log('res: ', a); // will print res: 2023-01-30T00:00:00.000Z
CodePudding user response:
In a functional programming way given your new requirements:
const allDays = ["MON", "TUE", "WED", "THU", "FRI", "SAT", "SUN"];
const startDate = "31/01/2023";
const endDate = "26/02/2023";
// Convert a "dd/MM/yyyy" string into a Date object
function convertToDate(dateString) {
let d = dateString.split("/");
let dat = new Date(d[2] '/' d[1] '/' d[0]);
return dat;
}
function findDate (arrayDay, startRange, endRange) {
const dayToJSDay = {
1: "MON",
2: "TUE",
3: "WED",
4: "THU",
5: "FRI",
6: "SAT",
7: "SUN",
};
const s = convertToDate(startRange);
const e = convertToDate(endRange);
const nextDay = a => a 1
const previousDay = a => a - 1
return [
findDateRec(dayToJSDay, arrayDay, s, e, nextDay),
findDateRec(dayToJSDay, arrayDay, e, s, previousDay)
]
};
function findDateRec (days, day, curDate, endDate, op) {
if(day.some(d => days[curDate.getDay()] === d)) return curDate;
if(curDate.setHours(0,0,0,0) == endDate.setHours(0,0,0,0)) return null;
const nextDay =new Date(curDate);
nextDay.setDate(op(curDate.getDate()))
return findDateRec(days,day,nextDay,endDate, op)
}
const a = findDate(["MON", "FRI"], startDate, endDate);
console.log('res: ', a); // res: [ 2023-02-03T00:00:00.000Z, 2023-02-24T00:00:00.000Z ]
CodePudding user response:
The following snippet does it without any iteration:
// SUN:0, MON:1,TUE:2 ... SAT:6
const fromTo=[ new Date(2023,0,28), new Date(2023,1,26) ];
const findDate = wd =>
fromTo.map((d,i)=>(d=new Date(d),d.setDate(d.getDate() ((i?-7:7)-d.getDay() wd[i])%7),d))
// example: MON,FRI
console.log(findDate([1,5]).map(d=>d.toLocaleString()))
Please note that the weekdays are entered numerically (see comment in the first line of the code). The function will then return an array with starting and end dates having the specified weekdays after the start date and before the end date respectively.
CodePudding user response:
if i understand it correctly, this is a clean, self documenting approach
const startDate = new Date(2023, 1,28 );
const endDate = new Date(2023,2,21);
const days = ['SUN', 'MON', 'TUE', 'WED', 'THU', 'FRI', 'SAT'];
const dayInMillis = 86_400_000
const findFirstDayInDateRange = ()=>{
}
const findLastDayInDateRange = ()=>{
return recurseDatesForDay(endDate, -dayInMillis, 5)
}
const recurseDatesForDay = (date, dateStepMillis, targetDayIndex)=>{
if(date.getDay() === targetDayIndex) return date;
return recurseDatesForDay(new Date(date.getTime() dateStepMillis), dateStepMillis, targetDayIndex)
}
console.log('....', findLastDayInDateRange())