How to manipulate dates for Tri-monthly payment dates using javascript - javascript

How to can I make this sequence of date with tri-monthly. for eg. the input is `"2022-03-14" the input is dynamic it depends on the user input... I'm trying add + 10 days but isn't working
The output I want
[
"2022-03-24",
"2022-04-04",
"2022-04-14",
"2022-04-24",
"2022-05-04",
"2022-05-14",
"2022-05-24",
"2022-06-04",
"2022-06-14",
"2022-06-24",
]
My code output which is worng
[
"2022-03-24",
"2022-04-14",
"2022-04-24",
"2022-05-14",
"2022-05-24",
"2022-06-14",
"2022-06-24",
"2022-07-14",
"2022-07-24",
]
function createSchedule(date, count){
date = new Date(date);
let day = date.getDate();// Get day in given date
let k = 0;
let days = k? [day - 10, day , day + 10] : [day, day + 10, day- 10];
let result = [];
if(day > 10){
k = +0
}else{
if(day > 20 ){
k = +1
}else{
k= +2
}
}
for(let i = 0; i < count; i++){
k= 1-k;
date.setDate(days[k]);
// When date overflows into next month, take last day of month
if (date.getDate() !== days[k]) date.setDate(0);
if (!k) date.setMonth(date.getMonth() + 1);
result.push(date.toLocaleDateString("en-SE"));
}
return result
}
var dateRelease = new Date("03-14-2022");
var result = createSchedule(dateRelease, 9);
console.log(result)

A few issues in your attempt:
After let k = 0, the conditional operator on k? will always evaluate the first expression after ?, which is [day - 10, day , day + 10].
That array could have dates that are greater than 31 (day + 10)
That other array [day, day + 10, day- 10] is not sorted, but should be.
The constants +0 and +1 and +2 are OK, but it looks odd that you use the unary plus here. It could just be 0, 1 and 2.
The assignment k = 1 - k assumes you only have two entries in your days array, but you have three, so use modular arithmetic: k = (k + 1) % 3
Here is a correction:
function createSchedule(date, count) {
date = new Date(date);
let day = date.getDate();
let firstDay = 1 + (day - 1) % 10;
let days = [firstDay, firstDay + 10, firstDay + 20];
let k = days.indexOf(day);
let result = [];
for (let i = 0; i < count; i++) {
k = (k + 1) % 3;
date.setDate(days[k]);
// When date overflows into next month, take last day of month
if (date.getDate() !== days[k]) date.setDate(0);
if (!k) date.setMonth(date.getMonth() + 1);
result.push(date.toLocaleDateString("en-SE"));
}
return result;
}
var dateRelease = new Date("2022-03-14");
var result = createSchedule(dateRelease, 25);
console.log(result);

Related

How to manipulate date using Javascript

How can I achieve this sequence of date output if the user input is 04-29-2022 and the output is like this
What I want:
2022-05-14
2022-05-29
2022-06-14
2022-06-29
2022-07-14
2022-07-29
2022-08-14
2022-08-29
my code output
2022-05-13
2022-05-28
2022-06-12
2022-06-27
2022-07-12
2022-07-27
2022-08-11
2022-08-26
var dateRelease = new Date("04-29-2022")
const terms = 8
for (let i = 0; i < terms; i++) {
console.log(new Date(dateRelease.setDate(dateRelease.getDate() + 15)).toISOString().slice(0, 10))
}
Here is a function that takes the day of the month in the given date and determines which other date of the month would be needed in the output (either 15 more or 15 less). Then it generates dates alternating between those two date-of-the-month, and when it is the lesser of those two, incrementing the month. In case a date is invalid and automatically overflows into the next month, it is corrected to the last day of the intended month.
To format the date in the output, it is better to not use toISODateString as that interprets the date as a UTC Date, while new Date("2022-04-29") interprets the given string as a date in the local time zone. This can lead to surprises in some time zones. So I would suggest using toLocaleDateString with a locale that produces your desired format.
Here is the code:
function createSchedule(date, count) {
date = new Date(date);
let day = date.getDate();
let k = +(day > 15);
let days = k ? [day - 15, day] : [day, day + 15];
let result = [];
for (let i = 0; i < count; i++) {
k = 1 - k;
date.setDate(days[k]);
// When date overflows into next month, take last day of month
if (date.getDate() !== days[k]) date.setDate(0);
if (!k) date.setMonth(date.getMonth() + 1);
result.push(date.toLocaleDateString("en-SE"));
}
return result;
}
var dateRelease = new Date("2022-04-29");
var result = createSchedule(dateRelease, 25);
console.log(result);
var dateRelease = new Date("04-29-2022")
const terms = 8
for (let i = 0; i < terms; i++) {
let date = new Date(dateRelease.setDate(dateRelease.getDate() + 15)).toLocaleDateString('en-US');
let format = date.split('/').map(d => d.padStart(2 ,'0')).join('-')
console.log(format);
}

DateTime datesAgo collection function

Hi I need help with tweaking my datesAgo function. What it does is it gives me a collection of dates from the date that is passed through counting backwards but my problem with my function is that it's not showing the 3rd date correctly it should be 17 instead of 16 can someone see if they know why it's happing like that
Date.prototype.datesAgo = function(num) {
let date = this;
let arr = [];
for(let i = 0; i < num; i++) {
arr.push(i.toString());
}
let days = arr.slice(0, num).join(' ');
console.log(days)
return days.split(' ').map(function(n) {
date.setDate(date.getDate() - n);
return (function(year, month, day) {
return [year, month < 10 ? '0'+ month : month, day < 10 ? '0' + day : day].join('-');
})(date.getFullYear(), date.getMonth(), date.getDate());
}).join(',');
}
console.log(new Date('2018-05-19').datesAgo(3))
On each iteration, you're mutating the original date object:
date.setDate(date.getDate() - n);
So, on each subsequent iteration, you're subtracting n from the last iteration's date, not the original date. Clone the original date object on each iteration instead:
Date.prototype.datesAgo = function(num) {
const date = this;
const dateStrs = Array.from({ length: num }, (_, i) => {
const clonedDate = new Date(date.getTime());
clonedDate.setDate(date.getDate() - i);
return (function(year, month, day) {
return [year, month < 10 ? '0' + month : month, day < 10 ? '0' + day : day].join('-');
})(clonedDate.getFullYear(), clonedDate.getMonth(), clonedDate.getDate());
});
return dateStrs.join(',');
}
console.log(new Date('2018-05-19').datesAgo(3))

js datepicker - allow non-consecutive days pcm

I would like to limit users to selecting only the first and third Monday of each month. We have a volunteer intake only on these days, so I want to limit incorrect date selections as much as possible.
I'm not a js coder, but have managed to adapt some code I found online to allow the first or third Monday of each month, but I can't work out how to allow both of them.
Here's the code I have for the first Monday:
var firstMonday = new Date(date);
var mondays=0;
firstMonday.setDate(1);
while (mondays < 1) {
firstMonday.setDate(firstMonday.getDate() + 1);
if (firstMonday.getDay() == 1) {
mondays++;
}
}
var result = date.getDate() != firstMonday.getDate();
I think this is what you are asking. Credit to jabclab for the getMondays() function.
// test: first monday of this month
// result: true
//var dates = [new Date(2017,8,4)];
// test: third monday of this month
// result: true
//var dates = [new Date(2017,8,18)];
// test: first and third monday of this month
// result: true
var dates = [new Date(2017,8,4), new Date(2017,8,18)];
// test: first monday, third monday, and random day from this month
// result: false
//var dates = [new Date(2017,8,4), new Date(2017,8,18), new Date(2017,8,22)];
alert(validate(dates));
function validate(dates) {
var valid = true;
var mondays = getMondays();
var firstMonday = mondays[0].setHours(0,0,0,0);
var thirdMonday = mondays[2].setHours(0,0,0,0);
if (dates && dates.length > 0) {
for (var i = 0; i < dates.length; i++) {
// Zero out time so only year, month, and day is compared
var d = dates[i].setHours(0,0,0,0);
if (d != firstMonday && d != thirdMonday) {
return false;
}
}
}
else {
valid = false;
}
return valid;
}
function getMondays() {
var d = new Date(),
month = d.getMonth(),
mondays = [];
d.setDate(1);
// Get the first Monday in the month
while (d.getDay() !== 1) {
d.setDate(d.getDate() + 1);
}
// Get all the other Mondays in the month
while (d.getMonth() === month) {
mondays.push(new Date(d.getTime()));
d.setDate(d.getDate() + 7);
}
return mondays;
}
Thanks, but I'm not sure if the above works or not as I was looking for a js code answer - I'll leave that for someone else to work out.
...which I've found in the meantime. Many thanks to Hugh at Fabrik for the following:
var thisdate = new Date(date);
thisdate.setHours(0,0,0,0);
var day = 1; // monday
var nth = 1; // first
var first = new Date(thisdate.getFullYear(), thisdate.getMonth(), 1),
add = (day - first.getDay() + 7) % 7 + (nth - 1) * 7;
first.setDate(1 + add);
nth = 3; // third
var third = new Date(thisdate.getFullYear(), thisdate.getMonth(), 1),
add = (day - third.getDay() + 7) % 7 + (nth - 1) * 7;
third.setDate(1 + add);
//console.log(thisdate + ', ' + first + ', ' + third);
var result = (first.getTime() !== thisdate.getTime()) && (third.getTime() !== thisdate.getTime());

Javascript: Input date - current date function is close but not quite right?

I am trying to code a function that when given a past date will calculate years, months, and days since then in a trickle down remainder fashion. As in "2 years, 1 month, and 3 days.", not total time in all 3 formats (2 years = 24 months = 730 days).
Code:
//Function to tell years/months/days since birthday to today
var ageID = function(date){
var nowDate = new Date();
//current date
var nowYear = nowDate.getFullYear();
var nowMonth = nowDate.getMonth();
var nowDay = nowDate.getDay();
//input birthday
var year = date[0];
var month = date[1];
var day = date[2];
var longMonth = [1, 3, 5, 7, 8, 10, 12];
var shortMonth = [4, 6, 9, 11];
var febMonth = [2];
var specfMonth = 0;
//finding month that corresponds to 28, 30, or 31 days in length
for (i = 0; i < longMonth.length; i++){
if (longMonth[i] === month){
specfMonth = 31;
}
}
for (i = 0; i < shortMonth.length; i++){
if (shortMonth[i] === month){
specfMonth = 30;
}
}
for (i = 0; i < febMonth.length; i++){
if (febMonth[i] === month){
specfMonth = 28;
}
}
//Reduced input and current date
var redYear = nowYear - year - 1;
var redMonth = 0;
var redDay = 0;
//The following 2 if/else are to produce positive output instead of neg dates.
if (nowMonth < month){
redMonth = month - nowMonth;
}else{
redMonth = nowMonth - month;
}
if (nowDay < day){
redDay = day - nowDay;
}else{
redDay= nowDay - day;
}
var adjMonth = 12 - redMonth;
var adjDay = specfMonth - redDay;
if (redYear < 1){
return adjMonth + " months, " + adjDay + " days ago.";
}else{
return redYear + " years, " + adjMonth + " months, " + adjDay + " days ago.";
}
};
console.log(ageID([2001, 9, 11]));
Output:
13 years, 10 months, 20 days ago.
However, the accurate output would be:
13 years, 10 months, 30 days ago.
Your issue is : var nowDay = nowDate.getDay();
You should use: nowDate = nowDate.getDate(); instead.
getDay() return the number of day in the week.
Monday is "1", Tuesday is "2", etc.

How can I add n days to a date but exclude Sundays using yyyymmdd format?

I want a date after 'n' days from a given date in 'yyyymmdd' format (output is also in same format).Adding n days should exclude Sundays. Is it possible to do this in javascript?
Here is my code to add n days to a date
function mydate(dateStr,offset)
{
var ymd = dateStr.match(/^(\d{4})(\d{2})(\d{2})$/);
if (ymd)
{
var date = new Date(ymd[1], ymd[2] - 1, ymd[3]);
date.setDate(date.getDate() + offset);
return $.datepicker.formatDate('yymmdd', date);
}
else
{ // parse error
return null;
}
}
for example,
mydate('19890831',10)
will return
19890910
but actually what I need is '19891012' because there are 2 Sundays when we add 10 days to the '19890831'
Simple solution; you can just loop through the days and skip sundays:
while (offset > 0) {
date.setDate(date.getDate() + 1);
if (date.getDay() != 0) offset--;
}
You can refer to answer here to figure out how many sundays are there between two dates once you have that you can simply add that number to your original days diff.
How to determine number Saturdays and Sundays comes between two dates in java script
function pad(n){
if(n < 10){
return "0" + n;
}
return n;
}
function addDays(dt, n){
var matches = dt.match(/^(\d{4})(\d{2})(\d{2})$/);
var year = matches[1];
var month = matches[2];
var day = matches[3];
var dt = new Date(year, month - 1, day);
var weekDay = dt.getDay();
if((weekDay + n) > 6){
n = n + 1;
}
if(weekDay === 0){
n = n + 1;
}
var oneDayInMillis = 1 * 24 * 60 * 60 * 1000;
var newDt = new Date(dt.getTime() + (oneDayInMillis * n));
return "" + newDt.getFullYear() + pad(newDt.getMonth() + 1) + pad(newDt.getDate());
}

Categories

Resources