Reputation: 15
At the end of my code, you will notice that the elements being added to the array datesArr are somehow being copied to the element in front of it. Also not sure why I'm unable to get the expected output
Example:
1) Starting datesArr = [04/30/2022]
2) Adding date 03/30/2022 to datesArr1 overwrites datesArr[0] so then I have an array output that looks like
[04/30/2022, 04/30/2022]
as opposed to
[04/30/2022, 03/30/2022]
If given a month-end in Date format and a frequency,
return an array which includes the given month-end and the 11 preceding month-ends by frequency.
//Goal: Populate the datesArr with a list of monthend dates for 12 preceding periods(12 elements in array)
/*
Initialize Variables
datesArray - Holds all dates
initialDate - first month end date that will be placed in the array and every preceding month-end will be calculated based on it
targetDate - Target date is the month end date at the time that will be used to calculate the next preceding month end
frequecy - value that will be used to determine frequency of months (E.g. 1 = 1 month(Monthly), 3 = 3 months(quarterly)). This vaule is used in deltaOfDays function
period - represent the number of month end dates that should be included in the array (E.g. period of 12 is an datesArr of 12 elements)
duration of months - repsents the number of months between month ends(E.g. durationOfMonths = 3 , means quarterly 04/30/2022 to 01/31/2022)
*/
let datesArr = [];
const initialDate = new Date (2022, 03, 30);
let targetDate;
const period = 12;
const durationOfMonths = 1;
//Step1: initialize first element of datesArr with initialDate value and other elements used in for loop
datesArr[0] = initialDate
console.log(datesArr[0])
let numberOfDays; //calculated by deltaOfDays function and represents value of days to be subtracted from targetDate
let newMonthEndDate; // holds the newMonthEndDate value that will be added as the next element in datesArr after being calculated subtracting numberOfDays from targetDate
//Step2: Loop through array period number of times. On each loop identify target element and use it calculate subsequent month end date in the array
for (let i = 0; i < period; i++){
console.log("Loop iteration #" + i)
//assign array element to targetDate
targetDate = datesArr[i];
console.log("targetDate value is: " + targetDate)
//calculate the numberOfDays to subtract from the target date such as to arrive at the new monthend date by calling a function deltaOfDays
numberOfDays = deltaOfDays(targetDate, durationOfMonths)
console.log("The numberOfDays: " + numberOfDays);
//subtract the numberOfDays from the targetdate to arrive at newMonthEndDate which is stored as a Date object
newMonthEndDate = new Date(targetDate.setDate(targetDate.getDate() - numberOfDays));
console.log("newMonthEnd value: " + newMonthEndDate)
//assign newMonthEndDate as the next value in the datesArr
datesArr[i + 1] = newMonthEndDate
console.log(datesArr)
}
//Function
function deltaOfDays(targetDate, durationOfMonths){
//array of number of days per month in reverse (E.g. Jan = daysPerMonth[11])
const daysPerMonth = [31, 30, 31, 30, 31, 31, 30, 31, 30, 31, 28, 31]
//set index to begin array based number value of Month ( E.g. Apr = 3 + 1 = 4th index - 12 )
//targetDate = strToDateConvert(targetDate)
let i = Math.abs(targetDate.getMonth() - 12)
console.log("deltaDays(): i = " + i)
const j = i
//Start at initial month and loop through at durationOfMonths - 1 to account for initialization of element[0] already
for(i; i <= (i + durationOfMonths); i++ ){
//add days per month to sum
numberOfDays =+ daysPerMonth[j];
//remove first element of array(DEC) and add to the end
temp = daysPerMonth.shift()
daysPerMonth.push(temp)
return numberOfDays
}
}
Upvotes: 1
Views: 65
Reputation: 1
Firstly: I can't see all the issues in your code, since the code you have is so over complicated for what you want - if you want an answer that uses your code as a starting point, this isn't it :D
This answer takes advantage of the fact that
new Date(2022, 4, 0)
will result in the LAST day of April 2022 - i.e. since month is 0 based, it's like you're saying "give me the 0th day of May 2022" ... which is the day before the 1st May 2022 ... so, 30 April 2022
Knowing that, and the fact that negative numbers are also allowed in month (in fact in any argument) and the constructor will deal with it for you, the solution is really simple
new Date(2022, 4, 0) - April 30 2022
new Date(2022, 3, 0) - March 31 2022
new Date(2022, 2, 0) - February 28 2022
new Date(2022, 1, 0) - January 31 2022
new Date(2022, 0, 0) - December 31 2021
new Date(2022, -1, 0) - November 30 2021
... etc
Now - if you want the array to be actual Date objects, then the code is simply
const makeDates = (startYear, startMonth, duration = 1, length = 12) =>
Array.from({ length }, (_, index) =>
new Date(startYear, startMonth - index * duration, 0)
);
console.log(makeDates(2022, 4, 1));
console.log(makeDates(2022, 4, 3));
before rejecting this snippet, take note that the date is in UTC
If you just want strings as per your expected output:
const makeDates = (startYear, startMonth, duration = 1, length = 12) =>
Array.from({ length }, (_, index) =>
new Date(startYear, startMonth - index * duration, 0)
.toLocaleDateString("en-US")
.split("/")
.map((v) => v.padStart(2, 0))
.join("/")
);
console.log(makeDates(2022, 4, 1));
console.log(makeDates(2022, 4, 3));
Upvotes: 1