Home > Enterprise >  Find the first and the last days of an array of special days in a given period of time in JavaScript
Find the first and the last days of an array of special days in a given period of time in JavaScript

Time:01-29

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())
  • Related