I am getting data from microsoft outlook graph api and I am looking for generating recurring data structures. Problem is for some use cases my code completely fails . A example of that recurrence pattern is this
{
recurrence: {
pattern: {
type: "weekly",
interval: 1,
month: 0,
dayOfMonth: 0,
daysOfWeek: ["monday", "tuesday", "wednesday", "thursday", "friday"],
firstDayOfWeek: "sunday",
index: "first",
},
range: {
type: "endDate",
startDate: "2023-10-26T00:00:00.000Z",
endDate: "2023-11-10T23:59:00.000Z",
recurrenceTimeZone: "Romance Standard Time",
numberOfOccurrences: 0,
},
},
}
My code is following : -
export const generateRecurringDates = (appointment,end_date,start_date) => {
const { pattern, range } = appointment.recurrence;
const startDate = new Date(range.startDate);
let endDate;
let endTime;
if(range.type == 'noEnd'){
endDate = new Date(end_date);
endTime ='23:59:00.000Z'
}else{
endDate = new Date(range.endDate);
endTime =endDate.toISOString().split('T')[1]
}
const recurringDates = [];
let currentDate = startDate;
let startTime =currentDate.toISOString().split('T')[1]
let end;
if(endDate >= new Date(end_date)){
end = new Date(end_date)
}else{
end = endDate
}
let start;
let added = true;
if(startDate >= new Date(start_date)){
currentDate = start = startDate
}else{
added = false
currentDate = start = new Date(start_date)
}
// currentDate = new Date(currentDate.setDate(currentDate.getDate() - 1));
while (currentDate <= end) {
// Adjust the date based on the recurrence pattern
if(pattern?.daysOfWeek?.length > 0){
pattern?.daysOfWeek?.map((dayName) =>
{
var days = ['sunday', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday'];
if(pattern.type == 'relativeMonthly'){
recurringDates.push({
start: currentDate.toISOString().split('T')[0],
end: currentDate.toISOString().split('T')[0],
title: appointment.title
});
}else{
if(pattern?.daysOfWeek?.includes(days[currentDate.getDay()].toString()) && currentDate <= end){
recurringDates.push({
start: currentDate.toISOString().split('T')[0],
end: currentDate.toISOString().split('T')[0],
title: appointment.title
});
}
}
currentDate = adjustDate(currentDate, pattern,dayName);
}
);
}else{
if(currentDate <= end){
if(pattern.dayOfMonth > 0){
if(pattern.month > 0 && (pattern.month == (currentDate.getMonth()+1)) && pattern.dayOfMonth == currentDate.getDate()){
recurringDates.push({
start: currentDate.toISOString().split('T')[0],
end: currentDate.toISOString().split('T')[0]
});
}else if(pattern.month == 0 && pattern.dayOfMonth == currentDate.getDate()){
recurringDates.push({
start: currentDate.toISOString().split('T')[0],
end: currentDate.toISOString().split('T')[0]
});
}
}else{
recurringDates.push({
start: currentDate.toISOString().split('T')[0],
end: currentDate.toISOString().split('T')[0]
});
}
}
currentDate = adjustDate(currentDate, pattern);
}
}
return recurringDates;
}
function adjustDate(date, pattern,dayName ='') {
let newDate = new Date(date);
switch (pattern.type) {
case "daily":
newDate.setDate(newDate.getDate() + pattern.interval);
break;
case "weekly":
// Adjust for the specific day of the week if interval is 1
if (pattern.interval == 1) {
let days = ['sunday', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday'];
// let day = days.indexOf(dayName.toLowerCase());
}
if (dayName != '') {
var days = ['sunday', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday'];
var day = days.indexOf(dayName.toLowerCase());
let addDay = ((day + 7 - newDate.getDay()) % 7);
if(addDay == 0){
newDate.setDate(newDate.getDate() +1)
}else{
newDate.setDate(newDate.getDate() + (((day + 7 - newDate.getDay()) % 7) || 7))
}
} else {
newDate.setDate(newDate.getDate() + pattern.interval * 7);
}
break;
case "absoluteMonthly":
// Adjust for the specific day of the month
if (pattern.dayOfMonth) {
const currentMonth = newDate.getMonth();
const targetDayOfMonth = pattern.dayOfMonth;
if (targetDayOfMonth > newDate.getDate()) {
newDate.setDate(targetDayOfMonth);
} else {
// Move to the next month
newDate.setMonth(currentMonth + 1);
newDate.setDate(targetDayOfMonth);
}
} else {
newDate.setMonth(newDate.getMonth() + pattern.interval);
}
break;
// case "relativeMonthly":
// // Adjust for the specific day of the week
// if (pattern.daysOfWeek && pattern.daysOfWeek.length > 0) {
// const dayName = new Intl.DateTimeFormat('en-US', { weekday: 'long' }).format(newDate).toLowerCase();
// const targetDayIndex = pattern.daysOfWeek.indexOf(dayName);
// console.log(targetDayIndex)
// if (targetDayIndex >= 0) {
// let daysToAdd = getNthDayOfMonth(newDate, pattern.index, pattern.daysOfWeek);
// console.log(daysToAdd,'daysToAdd')
// if (daysToAdd === 0) {
// // If daysToAdd is zero, move to the next occurrence in the next month
// newDate.setDate(1);
// newDate.setMonth(newDate.getMonth() + pattern.interval);
// daysToAdd = getNthDayOfMonth(newDate, pattern.index, pattern.daysOfWeek);
// }
// newDate.setDate(daysToAdd);
// } else {
// newDate.setDate(newDate.getDate() +1)
// }
// } else {
// newDate.setMonth(newDate.getMonth() + pattern.interval);
// }
// break;
case "relativeMonthly":
if (pattern.daysOfWeek && pattern.daysOfWeek.length > 0) {
var days = ['sunday', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday'];
var day = days.indexOf(dayName.toLowerCase());
var nextOccurrence = findNthDayOfMonth(newDate.getFullYear(), newDate.getMonth(), day, pattern.index);
newDate = new Date(nextOccurrence);
} else {
newDate.setMonth(newDate.getMonth() + pattern.interval);
}
break;
case "absoluteYearly":
// Adjust for the specific day of the month
if (pattern.dayOfMonth > 0) {
const targetDate = new Date(newDate);
targetDate.setMonth(pattern.month - 1);
targetDate.setDate(pattern.dayOfMonth);
if (targetDate <= newDate) {
newDate.setFullYear(newDate.getFullYear() + pattern.interval);
newDate.setMonth(pattern.month - 1);
newDate.setDate(pattern.dayOfMonth);
} else {
newDate.setMonth(pattern.month - 1);
newDate.setDate(pattern.dayOfMonth);
}
} else {
newDate.setFullYear(newDate.getFullYear() + pattern.interval);
newDate.setMonth(pattern.month - 1);
newDate.setDate(1);
while (newDate.getDay() !== 0) {
newDate.setDate(newDate.getDate() + 1);
}
newDate.setDate(newDate.getDate() + (pattern.interval - 1) * 7);
}
break;
// case "relativeYearly":
// // Adjust for the specific day of the week
// if (pattern.daysOfWeek && pattern.daysOfWeek.length > 0) {
// if (dayName != '') {
// newDate.setFullYear(newDate.getFullYear() + pattern.interval);
// newDate.setMonth(pattern.month - 1);
// var days = ['sunday', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday'];
// var day = days.indexOf(dayName.toLowerCase());
// newDate.setDate(1); // Set to the first day of the month
// while (newDate.getDay() !== day) {
// // Move to the next day until it's a Friday
// newDate.setDate(newDate.getDate() + 1);
// }
// }
// } else {
// newDate.setFullYear(newDate.getFullYear() + pattern.interval);
// }
// break;
case "relativeYearly":
if (pattern.daysOfWeek && pattern.daysOfWeek.length > 0) {
var days = ['sunday', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday'];
var day = days.indexOf(dayName.toLowerCase());
var nextOccurrence = findNthDayOfMonth(newDate.getFullYear() + pattern.interval, pattern.month - 1, day, pattern.index);
newDate = new Date(nextOccurrence);
} else {
newDate.setFullYear(newDate.getFullYear() + pattern.interval);
}
break;
// Add more cases for other recurrence types if needed
default:
break;
}
return newDate;
}
this is constantly failing to get me code where recurrence pattern is above. Where am I making mistake in my logic.