Find first monday date of month - javascript

I have a date (usually the first day of a month but not necessary, it could be any date) and I want a new date corresponding to the first Monday of that month.
example:
findFirstMonday('1 jul 2021') -> 7 jul 2021
findFirstMonday('1 aug 2021') -> 2 aug 2021
findFirstMonday('13 aug 2021') -> 2 aug 2021
Here is my code that doesn't work:
const selectedDate = new Date();
const daysInSelectedDate = daysInMonth(selectedDate);
const lastDayPreviousMonth = addDays(selectedDate, daysInSelectedDate - selectedDate.getDate() + 1);
const firstDayPreviousMonth = removeDays(
lastDayPreviousMonth,
daysInMonth(lastDayPreviousMonth),
);
console.log('firstDayPreviousMonth: ', firstDayPreviousMonth);
let firstMonday = firstDayPreviousMonth;
while (firstDayPreviousMonth.getDay() !== 1) {
console.log('firstMonday: ', firstMonday, firstMonday.getDay());
firstMonday.setDate(firstMonday.getDate() + 1);
}
console.log('firstMonday: ', firstMonday, firstMonday.getDay());
function addDays(date, days) {
const result = new Date(date)
result.setDate(result.getDate() + days)
return result
}
function removeDays(date, days) {
const result = new Date(date)
result.setDate(result.getDate() - days)
return result
}
function daysInMonth(date) {
return new Date(date.getFullYear(), date.getMonth(), 0).getDate()
}
What am I wrong?
Thanks a lot

I came up with the following code. Some explanations about the general idea:
For a given date get the first date in the month of the given date. This is quite easy by generating a new Date object with day = 1 and the year and month of the given date.
Get the weekday of the first date.
Depending on the weekday of the first date, you must calculate which day number the first Monday has. This number is calculated by ((8 - firstWeekdayInMonth) % 7). You can easily verify yourself, that this always yields a Monday. The modulo is important for Sundays and Mondays, where you would otherwise add 8 and 7 respectively, which would not yield the first Monday anymore.
console.log(findFirstMonday('1 jul 21'))
console.log(findFirstMonday('1 aug 21'))
console.log(findFirstMonday('13 aug 21'))
function findFirstMonday(dateString) {
let targetDate = new Date(dateString);
let targetMonth = targetDate.getMonth();
let targetYear = targetDate.getFullYear();
let firstDateInMonth = new Date(targetYear, targetMonth, 1);
let firstWeekdayInMonth = firstDateInMonth.getDay();
let firstMondayDate = 1 + ((8 - firstWeekdayInMonth) % 7);
return new Date(targetYear, targetMonth, firstMondayDate).toLocaleDateString();
}

Edit:
console.log(findFirstMondayMonth('1 jul 2021').toLocaleDateString())
console.log(findFirstMondayMonth('1 aug 2021').toLocaleDateString())
console.log(findFirstMondayMonth('2 aug 2021').toLocaleDateString())
console.log(findFirstMondayMonth('13 aug 2021').toLocaleDateString())
function findFirstMonday(dateString) {
let date = new Date(dateString)
let diffDay = date.getDay() - 1
if (diffDay == -1) {
diffDay = 6
}
let mondayDate = new Date(dateString);
mondayDate.setHours(mondayDate.getHours() - diffDay*24)
return mondayDate
}
function findFirstMondayMonth(dateString) {
let date = new Date(dateString)
if (date.getMonth() == findFirstMonday(date).getMonth()) {
let dateOneWeekBefore = new Date(dateString)
dateOneWeekBefore.setHours(dateOneWeekBefore.getHours() - 24 * 7)
if (date.getMonth() == dateOneWeekBefore.getMonth()) {
return findFirstMondayMonth(dateOneWeekBefore)
} else {
return findFirstMonday(date)
}
} else {
let dateOneWeekAfter = new Date(dateString)
dateOneWeekAfter.setHours(dateOneWeekAfter.getHours() + 24 * 7)
return findFirstMonday(dateOneWeekAfter)
}
}
Sorry for the last answer, I think it was the first monday of week and I don't see Sunday.getMonth() == -1

Related

Get the past week 7 day period from a given date in Javascript

I am trying to get the date range of the past Wednesday to past Tuesday(7 days) from today's date.
Say the current date is 2022-05-01(May 1st), I am expecting the result to be the past Tuesday(end date) to Past Wednesday (start date = Past Tuesday -7 days)
i.e 20 April 2022 to 26 April 2022
function getStartAndEndDates () {
var now = new Date('2022-05-01'); //May 1st 2022
var day = now.getDay();
var diff = (day <= 2) ? (7 - 2 + day ) : (day - 2);
var PastTuesday = new Date();
var PastWednesday = new Date(PastTuesday.setDate(now.getDate() - diff));
console.log('End date is', PastTuesday.toISOString());
PastWednesday.setDate(PastTuesday.getDate() - 6);
console.log('Start Date is',PastWednesday.toISOString());
return[PastWednesday,PastTuesday];
}
Output obtained is:
End date is 2022-03-27T19:25:35.726Z //here month is set to March
Start Date is 2022-03-21T19:25:35.726Z
Expected Result is
End date is 2022-04-26T19:25:35.726Z // month is supposed to be April
Start Date is 2022-04-20T19:25:35.726Z
How can I change the code to get the expected result?
You should do something like
function getLastWeek(date) {
var today = new Date(date);
var lastWeek = new Date(today.getFullYear(), today.getMonth(), today.getDate() - 7);
return lastWeek;
}
// Your DATE
date = '2022-05-01'
//
var lastWeek = getLastWeek(date);
var lastWeekMonth = lastWeek.getMonth() + 1;
var lastWeekDay = lastWeek.getDate();
var lastWeekYear = lastWeek.getFullYear();
var lastWeekDisplay = lastWeekMonth + "/" + lastWeekDay + "/" + lastWeekYear;
console.log(lastWeekDisplay);
In your code:
var now = new Date('2022-05-01'); //May 1st 2022
Dates in the format YYYY-MM-DD are parsed as UTC, so the above will create a date object representing 2022-05-01T00:00:00Z.
var day = now.getDay();
This will return the local day number. For users with a zero or positive offset, it will return 0 (Sunday) but for users with a negative offset, it will return 6 (Saturday) because their local date is still the previous day.
var diff = (day <= 2) ? (7 - 2 + day ) : (day - 2);
Given day is 0 (for me), the above sets diff to 5.
var PastTuesday = new Date();
This creates a date for "now", which for me is 17 April.
var PastWednesday = new Date(PastTuesday.setDate(now.getDate() - diff));
In the above, now.getDate returns 1, and 1 - 5 is -4, so it sets the date for PastTuesday to -4. Now PastTuesday is in April, so it is set to 4 days prior to the start of April, i.e. 27 March.
Note that this adjusts PastTuesday and creates a copy for PastWednesday at the same time.
console.log('End date is', PastTuesday.toISOString());
Shows the equivalent UTC date and time, with the time representing the time that the code was run.
PastWednesday.setDate(PastTuesday.getDate() - 6);
Sets PastWednesday to 6 days prior to PastTuesday.
Anyhow, what is required is to do everything either as UTC or local, don't mix the two.
Sticking to code as closely as possible to the original and assuming a timestamp in YYYY-MM-DD format is parsed to the function, consider the following, which does everything as local:
// Parse timestamp in YYYY-MM-DD format as local
function parseISOLocal(s = new Date().toLocaleDateString('en-CA')) {
let [y, m, d] = s.split(/\D/);
return new Date(y, m-1, d);
}
// Get week Wed to Tue prior to passed date
function getStartAndEndDates (date) {
// Parse timestamp as local
var pastTuesday = parseISOLocal(date);
// Adjust pastTuesday to previous Tuesday
var day = pastTuesday.getDay();
var diff = (day <= 2) ? (7 - 2 + day ) : (day - 2);
var pastWednesday = new Date(pastTuesday.setDate(pastTuesday.getDate() - diff));
console.log('End date is', pastTuesday.toDateString());
// Adjust pastWednesday to previous Wednesday
pastWednesday.setDate(pastTuesday.getDate() - 6);
console.log('Start Date is',pastWednesday.toDateString());
return [pastWednesday, pastTuesday];
}
// Sunday 1 May 2022
console.log(getStartAndEndDates('2022-05-01').map(d => d.toDateString()));
// Current date
console.log(getStartAndEndDates().map(d => d.toDateString()));

How to check if last day of month is on friday Javascript

I'm supposed to write a code for codewars to find out the number of times a month ends with a Friday within a range of years.
To start off, I did research and found out several solutions but I still couldn't figure out the results in the console.log.
The first solution is from this tutorial:
In this code, the solution is
let LastDay = new Date(1998, 5 + 1, 0).getDate();
I was able to get the date, but it wasn't clear which day the date falls upon.
Then I found another solution at w3schools. This solution also set the date to be the last day of this month:
var d = new Date();
d.setMonth(d.getMonth() +1, 0);
document.getElementById("demo").innerHTML = d;
However, it works if it displays it as innerHTML = Sat Nov 30 2019 00:57:09 GMT-0500 (Eastern Standard Time). However, when I tried to rewrite the code and console.log it like in this example:
let d = new Date();
let month = d.getMonth()+1;
let lastday = d.setMonth(month, 0);
console.log(lastday);
The result I got was 1575093343211. I don't understand how it displays those numbers instead of the dates I was expecting. I thought that if it does display the dates, starting with the day, I can convert the date to string or array and check if the first element is Friday and then add it to the counter in the code I'm writing. How do I get the code to display the way I want it to.
something like this will work...
function LastDayOfMonth(Year, Month) {
return new Date((new Date(Year, Month, 1)) - 1);
}
var d = LastDayOfMonth(new Date().getYear(), new Date().getMonth())
//var d = LastDayOfMonth(2009, 11)
var dayName = d.toString().split(' ')[0];
console.log(dayName)
The result I got was 1575093343211. I don't understand how it displays those numbers instead of the dates I was expecting
Because you console.log the output of the setMonth method, not the date object:
let lastday = d.setMonth(month, 0);
console.log(lastday);
According to the documentation, the setMonth method returns:
The number of milliseconds between 1 January 1970 00:00:00 UTC and the updated date.
Instead you should use that output to create a new instance of the date object:
let lastday = new Date(d.setMonth(month, 0));
console.log(lastday);
Algorithms to get the last day of the month are generally based on setting a date to day 0 of the following month, which ends up being the last day of the required month.
E.g. to get the last day for June, 2019 (noting that 6 is July, not June):
let endOfJune = new Date(2019, 6, 0):
Once you have the date, you can get the day where 0 is Sunday, 1 is Monday, etc. and 5 is Friday:
let endOfJuneDay = endOfJune.getDay();
The set* methods modify the Date they're called on and return the time value for the modified date. So you don't need to assign the result to anything:
let d = new Date();
let month = d.getMonth() + 1;
// Set date to the new month
d.setMonth(month, 0);
console.log(d);
So if you want to loop over the months for a range of years and get the number that end with a Friday (or any particular day), you might loop over the months something like:
/*
** #param {number} startYear - start year of range
** #param {number} endYear - end year of range
** #param {number} dat - day number, 0 = Sunday, 1 = Monday, etc.
** default is 0 (Sunday)
*/
function countEOMDay(startYear, endYear, day = 0) {
// startYear must be <= end year
if (startYear > endYear) return;
// Start on 31 Jan of start year
let start = new Date(startYear, 0, 31);
// End on 31 Dec of end year
let end = new Date(endYear, 11, 31);
let count = 0;
// Loop over months from start to end
while (start <= end) {
// Count matching days
if (start.getDay() == day) {
++count;
}
// Increment month to end of next month
start.setMonth(start.getMonth() + 2, 0);
}
return count;
}
console.log(countEOMDay(2019, 2019, 5)); // 1
console.log(countEOMDay(2018, 2019, 5)); // 3
You can use setMonth() method to set the month of a date object. The return value of setMonth() method is milliseconds between the date object and midnight January 1 1970. That's what you get from console.log(lastday);
Your return value,
1575093343211
is milliseconds between your date object (d) and midnight January 1 1970.
If you want to get the expected date, you have to console log your date object instead the lastday, as follows:
let d = new Date();
let month = d.getMonth()+1;
let lastday = d.setMonth(month, 0);
console.log(d);
output: Sat Nov 30 2019 00:02:47 GMT+0530 (India Standard Time)
This is an alternative solution I wrote to solve your problem. This will return the number of times a month ends with a Friday within a range of years. Hope this will help you :)
var days = [];
var count = 0;
function getLastFridaysCount(startYear, endYear) {
for (var year = startYear; year <= endYear; year++) {
days = [
31,
0 === year % 4 && 0 !== year % 100 || 0 === year % 400 ? 29 : 28,
31, 30, 31, 30, 31, 31, 30, 31, 30, 31
];
for (var month = 0; month <= 11; month++) {
var myDate = new Date();
myDate.setFullYear(year);
myDate.setMonth(month);
myDate.setDate(days[month]);
if(myDate.getDay() == 5)
{
count++;
}
}
}
return count;
}
console.log("count", getLastFridaysCount(2014, 2017));
this is the solution, in the code can find the comments "//" explaining of what happens in each iteration.
function lastDayIsFriday(initialYear, endYear) {
let count = 0;
//according to when the year ends starts the loop
if (endYear !== undefined) {
let start = new Date(initialYear, 0, 31);
let end = new Date(endYear, 11, 31);
while(start <= end) { //check if the start date is < or = to the end
//The getDay() method returns the day of the week (from 0 to 6) for the specified date.
if(start.getDay() === 5) { //if = to FriYAY!!!
count++; //count the day
}
start.setMonth(start.getMonth()+2, 0);// returns the month (from 0 to 11) .getMonth
} //& sets the month of a date object .setMonth
return count;
} else {
let start = new Date(initialYear, 0, 31);
console.log(start.toString());
for(let i = 0; i < 12; i++) {
if(start.getDay() === 5) {
count++;
}
start.setMonth(start.getMonth() + 2, 0);
// console.log(start.toString());
}
return count;
}
}

group by weeks,days and year javascript [duplicate]

I have today = new Date(); object. I need to get first and last day of the current week. I need both variants for Sunday and Monday as a start and end day of the week. I am little bit confuse now with a code. Can your help me?
var curr = new Date; // get current date
var first = curr.getDate() - curr.getDay(); // First day is the day of the month - the day of the week
var last = first + 6; // last day is the first day + 6
var firstday = new Date(curr.setDate(first)).toUTCString();
var lastday = new Date(curr.setDate(last)).toUTCString();
firstday
"Sun, 06 Mar 2011 12:25:40 GMT"
lastday
"Sat, 12 Mar 2011 12:25:40 GMT"
This works for firstday = sunday of this week and last day = saturday for this week. Extending it to run Monday to sunday is trivial.
Making it work with first and last days in different months is left as an exercise for the user
Be careful with the accepted answer, it does not set the time to 00:00:00 and 23:59:59, so you can have problems.
You can use a third party date library to deal with dates. For example:
var startOfWeek = moment().startOf('week').toDate();
var endOfWeek = moment().endOf('week').toDate();
EDIT: As of September 2020, using Moment is discouraged for new projects (blog post)
Another popular alternative is date-fns.
You can also use following lines of code to get first and last date of the week:
var curr = new Date;
var firstday = new Date(curr.setDate(curr.getDate() - curr.getDay()));
var lastday = new Date(curr.setDate(curr.getDate() - curr.getDay()+6));
Hope it will be useful..
The excellent (and immutable) date-fns library handles this most concisely:
const start = startOfWeek(date);
const end = endOfWeek(date);
Default start day of the week is Sunday (0), but it can be changed to Monday (1) like this:
const start = startOfWeek(date, {weekStartsOn: 1});
const end = endOfWeek(date, {weekStartsOn: 1});
Here's a quick way to get first and last day, for any start day.
knowing that:
1 day = 86,400,000 milliseconds.
JS dates values are in milliseconds
Recipe: figure out how many days you need to remove to get the your week's start day (multiply by 1 day's worth of milliseconds). All that is left after that is to add 6 days to get your end day.
var startDay = 1; //0=sunday, 1=monday etc.
var d = now.getDay(); //get the current day
var weekStart = new Date(now.valueOf() - (d<=0 ? 7-startDay:d-startDay)*86400000); //rewind to start day
var weekEnd = new Date(weekStart.valueOf() + 6*86400000); //add 6 days to get last day
Small change to #Chris Lang answer.
if you want Monday as the first day use this.
Date.prototype.GetFirstDayOfWeek = function() {
return (new Date(this.setDate(this.getDate() - this.getDay()+ (this.getDay() == 0 ? -6:1) )));
}
Date.prototype.GetLastDayOfWeek = function() {
return (new Date(this.setDate(this.getDate() - this.getDay() +7)));
}
var today = new Date();
alert(today.GetFirstDayOfWeek());
alert(today.GetLastDayOfWeek());
Thaks #Chris Lang
This works across year and month changes.
Date.prototype.GetFirstDayOfWeek = function() {
return (new Date(this.setDate(this.getDate() - this.getDay())));
}
Date.prototype.GetLastDayOfWeek = function() {
return (new Date(this.setDate(this.getDate() - this.getDay() +6)));
}
var today = new Date();
alert(today.GetFirstDayOfWeek());
alert(today.GetLastDayOfWeek());
You could do something like this
var today = new Date();
var startDay = 0;
var weekStart = new Date(today.getDate() - (7 + today.getDay() - startDay) % 7);
var weekEnd = new Date(today.getDate() + (7 - today.getDay() - startDay) % 7);
Where startDay is a number from 0 to 6 where 0 stands for Sunday (ie 1 = Monday, 2 = Tuesday, etc).
SetDate will sets the day of the month. Using setDate during start and end of the month,will result in wrong week
var curr = new Date("08-Jul-2014"); // get current date
var first = curr.getDate() - curr.getDay(); // First day is the day of the month - the day of the week
var last = first + 6; // last day is the first day + 6
var firstday = new Date(curr.setDate(first)); // 06-Jul-2014
var lastday = new Date(curr.setDate(last)); //12-Jul-2014
If u setting Date is 01-Jul-2014, it will show firstday as 29-Jun-2014 and lastday as 05-Jun-2014 instead of 05-Jul-2014
So overcome this issue i used
var curr = new Date();
day = curr.getDay();
firstday = new Date(curr.getTime() - 60*60*24* day*1000); //will return firstday (ie sunday) of the week
lastday = new Date(firstday.getTime() + 60 * 60 *24 * 6 * 1000); //adding (60*60*6*24*1000) means adding six days to the firstday which results in lastday (saturday) of the week
I recommend to use Moment.js for such cases. I had scenarios where I had to check current date time, this week, this month and this quarters date time. Above an answer helped me so I thought to share rest of the functions as well.
Simply to get current date time in specific format
case 'Today':
moment().format("DD/MM/YYYY h:mm A");
case 'This Week':
moment().endOf('isoweek').format("DD/MM/YYYY h:mm A");
Week starts from Sunday and ends on Saturday if we simply use 'week' as parameter for endOf function but to get Sunday as the end of the week we need to use 'isoweek'.
case 'This Month':
moment().endOf('month').format("DD/MM/YYYY h:mm A");
case 'This Quarter':
moment().endOf('quarter').format("DD/MM/YYYY h:mm A");
I chose this format as per my need. You can change the format according to your requirement.
//get start of week; QT
function _getStartOfWeek (date){
var iDayOfWeek = date.getDay();
var iDifference = date.getDate() - iDayOfWeek + (iDayOfWeek === 0 ? -6:1);
return new Date(date.setDate(iDifference));
},
function _getEndOfWeek(date){
return new Date(date.setDate(date.getDate() + (7 - date.getDay()) === 7 ? 0 : (7 - date.getDay()) ));
},
*current date == 30.06.2016 and monday is the first day in week.
It also works for different months and years.
Tested with qunit suite:
QUnit.module("Planung: Start of week");
QUnit.test("Should return start of week based on current date", function (assert) {
var startOfWeek = Planung._getStartOfWeek(new Date());
assert.ok( startOfWeek , "returned date: "+ startOfWeek);
});
QUnit.test("Should return start of week based on a sunday date", function (assert) {
var startOfWeek = Planung._getStartOfWeek(new Date("2016-07-03"));
assert.ok( startOfWeek , "returned date: "+ startOfWeek);
});
QUnit.test("Should return start of week based on a monday date", function (assert) {
var startOfWeek = Planung._getStartOfWeek(new Date("2016-06-27"));
assert.ok( startOfWeek , "returned date: "+ startOfWeek);
});
QUnit.module("Planung: End of week");
QUnit.test("Should return end of week based on current date", function (assert) {
var endOfWeek = Planung._getEndOfWeek(new Date());
assert.ok( endOfWeek , "returned date: "+ endOfWeek);
});
QUnit.test("Should return end of week based on sunday date with different month", function (assert) {
var endOfWeek = Planung._getEndOfWeek(new Date("2016-07-03"));
assert.ok( endOfWeek , "returned date: "+ endOfWeek);
});
QUnit.test("Should return end of week based on monday date with different month", function (assert) {
var endOfWeek = Planung._getEndOfWeek(new Date("2016-06-27"));
assert.ok( endOfWeek , "returned date: "+ endOfWeek);
});
QUnit.test("Should return end of week based on 01-06-2016 with different month", function (assert) {
var endOfWeek = Planung._getEndOfWeek(new Date("2016-06-01"));
assert.ok( endOfWeek , "returned date: "+ endOfWeek);
});
QUnit.test("Should return end of week based on 21-06-2016 with different month", function (assert) {
var endOfWeek = Planung._getEndOfWeek(new Date("2016-06-21"));
assert.ok( endOfWeek , "returned date: "+ endOfWeek);
});
QUnit.test("Should return end of week based on 28-12-2016 with different month and year", function (assert) {
var endOfWeek = Planung._getEndOfWeek(new Date("2016-12-28"));
assert.ok( endOfWeek , "returned date: "+ endOfWeek);
});
QUnit.test("Should return end of week based on 01-01-2016 with different month and year", function (assert) {
var endOfWeek = Planung._getEndOfWeek(new Date("2016-01-01"));
assert.ok( endOfWeek , "returned date: "+ endOfWeek);
});
var dt = new Date() //current date of week
var currentWeekDay = dt.getDay();
var lessDays = currentWeekDay == 0 ? 6 : currentWeekDay-1
var wkStart = new Date(new Date(dt).setDate(dt.getDate()- lessDays));
var wkEnd = new Date(new Date(wkStart).setDate(wkStart.getDate()+6));
This will be useful for any date scenario.
Just using pure javascript, you can use the function below to get first day and last day of a week with freely setting day for start of week.
var weekday = [];
weekday[0] = "Sunday";
weekday[1] = "Monday";
weekday[2] = "Tuesday";
weekday[3] = "Wednesday";
weekday[4] = "Thursday";
weekday[5] = "Friday";
weekday[6] = "Saturday";
function getFirstDayOfWeek(date, from) {
//Default start week from 'Sunday'. You can change it yourself.
from = from || 'Sunday';
var index = weekday.indexOf(from);
var start = index >= 0 ? index : 0;
var d = new Date(date);
var day = d.getDay();
var diff = d.getDate() - day + (start > day ? start - 7 : start);
d.setDate(diff);
return d;
};
Last day of week is just 6 days after first day of week
function getLastDayOfWeek(date, from) {
from = from || 'Sunday';
var index = weekday.indexOf(from);
var start = index >= 0 ? index : 0;
var d = new Date(date);
var day = d.getDay();
var diff = d.getDate() - day + (start > day ? start - 1 : 6 + start);
d.setDate(diff);
return d;
};
Test:
getFirstDayOfWeek('2017-10-16'); //--> Sun Oct 15 2017
getFirstDayOfWeek('2017-10-16', 'Monday'); //--> Mon Oct 16 2017
getFirstDayOfWeek('2017-10-16', 'Tuesday'); //--> Tue Oct 10 2017
The biggest issue when the given date's week is in-between two months. (Like 2022-07-01, it's the 5th day of the week.)
Using getDay function we check if the week is in-between months.
Note: getDay() function identifies week start day as sunday, so it'll return 0 for sunday.
var curr = new Date(); // get current date
var weekdaynum = curr.getDay();
if(weekdaynum == 0){ //to change sunday to the last day of the week
weekdaynum = 6;
} else{
weekdaynum = weekdaynum-1;
}
var firstweek = curr.getDate() - weekdaynum;
var lastweek = firstweek + 6; // last day is the first day + 6
if((curr.getDate()-weekdaynum) <= 0){
var firstweek_lasmonth_lastdate = new Date(currweek.getFullYear(),currweek.getMonth(), 0);
var firstweek_diff = firstweek_lasmonth_lastdate.getDate()-Math.abs(firstweek);
var firstweekday = new Date(currweek.getFullYear(),currweek.getMonth()-1,firstweek_lasmonth_lastdate.getDate()+firstweek_diff);
var lastweekday = new Date(currweek.getFullYear(),currweek.getMonth()-1,firstweek_lasmonth_lastdate.getDate()+firstweek_diff+7);
} else{
var firstweekday = new Date(curr.setDate(firstweek));
var lastweekday = new Date(curr.setDate(lastweek));
}
So this will return (given date is: 2022/07/01):
firstweekday = Mon Jun 27 2022 00:00:00
lastweekday = Sun Jul 03 2022 00:00:00
Hope this helps.
krtek's method has some wrong,I tested this
var startDay = 0;
var weekStart = new Date(today.getDate() - (7 + today.getDay() - startDay) % 7);
var weekEnd = new Date(today.getDate() + (6 - today.getDay() - startDay) % 7);
it works
Although the question is seeming as obsolete I have to point out a problem.
Question: What will happen at 1st January 2016?
I think most of the above solutions calculate start of week as 27.12.2016.
For this reason I think, the correct calculation should be like the below simply;
var d = new Date(),
dayInMs = 1000 * 60 * 60 * 24,
weekInMs = dayInMs * 7,
startOfToday = new Date(d.getFullYear(), d.getMonth(), d.getDate()).valueOf(),
todayElapsedTime = d.valueOf() - startOfToday,
dayDiff = d.getDay() * dayInMs,
dateDiff = dayDiff + todayElapsedTime,
// finally
startOfWeek = d.valueOf() - dateDiff,
endOfWeek = startOfWeek + weekInMs - 1;
JavaScript
function getWeekDays(curr, firstDay = 1 /* 0=Sun, 1=Mon, ... */) {
var cd = curr.getDate() - curr.getDay();
var from = new Date(curr.setDate(cd + firstDay));
var to = new Date(curr.setDate(cd + 6 + firstDay));
return {
from,
to,
};
};
TypeScript
export enum WEEK_DAYS {
Sunday = 0,
Monday = 1,
Tuesday = 2,
Wednesday = 3,
Thursday = 4,
Friday = 5,
Saturday = 6,
}
export const getWeekDays = (
curr: Date,
firstDay: WEEK_DAYS = WEEK_DAYS.Monday
): { from: Date; to: Date } => {
const cd = curr.getDate() - curr.getDay();
const from = new Date(curr.setDate(cd + firstDay));
const to = new Date(curr.setDate(cd + 6 + firstDay));
return {
from,
to,
};
};
function getMonday(d) {
d = new Date(d);
var day = d.getDay(),
diff = d.getDate() - day + (day == 0 ? -6:1); // adjust when day is sunday
return new Date(d.setDate(diff));
}
console.log( getMonday(new Date(new Date().getFullYear(), new Date().getMonth(), new Date().getDate())) ) // Mon Nov 08 2010
Pure vanilla JS. no third party libraries.
const now = new Date()
const startOfWeek = new Date(now.getFullYear(), now.getMonth(), now.getDate() - now.getDay())
const endOfWeek = new Date(now.getFullYear(), now.getMonth(), startOfWeek.getDate() + 7)
^ this returns Sunday 00am to Sunday 00am. Adjust the "7" to get what you want.
var currentDate = new Date();
var firstday = new Date(currentDate.setDate(currentDate.getDate() - currentDate.getDay())).toUTCString();
var lastday = new Date(currentDate.setDate(currentDate.getDate() - currentDate.getDay() + 6)).toUTCString();
console.log("firstday", firstday);
console.log("lastday", lastday);
Works with different months and years.
let wDate = new Date();
let dDay = wDate.getDay() > 0 ? wDate.getDay() : 7;
let first = wDate.getDate() - dDay + 1;
let firstDayWeek = new Date(wDate.setDate(first));
let lastDayWeek = new Date(wDate.setDate(firstDayWeek.getDate()+6));
console.log(firstDayWeek.toLocaleDateString());
console.log(lastDayWeek.toLocaleDateString());
Nice suggestion but you got a small problem in lastday.
You should change it to:
lastday = new Date(firstday.getTime() + 60 * 60 *24 * 6 * 1000);
The moment approach worked for me for all the cases ( although i have not test the boundaries like year end , leap years ). Only Correction in the above code is the parameter is "isoWeek" , if you want to start the week from Monday.
let startOfWeek = moment().startOf("isoWeek").toDate();
let endOfWeek = moment().endOf("isoWeek").toDate();
We have added jquery code that shows the current week of days from monday to sunday.
var d = new Date();
var week = [];
var _days = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
var _months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
for (let i = 1; i <= 7; i++) {
let first = d.getDate() - d.getDay() + i;
let dt = new Date(d.setDate(first));
var _day = _days[dt.getDay()];
var _month = _months[dt.getMonth()];
var _date = dt.getDate();
if(_date < 10 ){
_date = '0' +_date;
}
var _year = dt.getFullYear();
var fulldate = _day+' '+_month+' '+_date+' '+_year+' ';
week.push(fulldate);
}
console.log(week);
An old question with lots of answers, so another one won't be an issue. Some general functions to get the start and end of all sorts of time units.
For startOf and endOf week, the start day of the week defaults to Sunday (0) but any day can be passed (Monday - 1, Tuesday - 2, etc.). Only uses Gregorian calendar though.
The functions don't mutate the source date, so to see if a date is in the same week as some other date (week starting on Monday):
if (d >= startOf('week', d1, 1) && d <= endOf('week', d1, 1)) {
// d is in same week as d1
}
or in the current week starting on Sunday:
if (d >= startOf('week') && d <= endOf('week')) {
// d is in the current week
}
// Returns a new Date object set to start of given unit
// For start of week, accepts any day as start
function startOf(unit, date = new Date(), weekStartDay = 0) {
// Copy original so don't modify it
let d = new Date(date);
let e = new Date(d);
e.setHours(23,59,59,999);
// Define methods
let start = {
second: d => d.setMilliseconds(0),
minute: d => d.setSeconds(0,0),
hour : d => d.setMinutes(0,0,0),
day : d => d.setHours(0,0,0,0),
week : d => {
start.day(d);
d.setDate(d.getDate() - d.getDay() + weekStartDay);
if (d > e) d.setDate(d.getDate() - 7);
},
month : d => {
start.day(d);
d.setDate(1);
},
year : d => {
start.day(d);
d.setMonth(0, 1);
},
decade: d => {
start.year(d);
let year = d.getFullYear();
d.setFullYear(year - year % 10);
},
century: d => {
start.year(d);
let year = d.getFullYear();
d.setFullYear(year - year % 100);
},
millenium: d => {
start.year(d);
let year = d.getFullYear();
d.setFullYear(year - year % 1000);
}
}
start[unit](d);
return d;
}
// Returns a new Date object set to end of given unit
// For end of week, accepts any day as start day
// Requires startOf
function endOf(unit, date = new Date(), weekStartDay = 0) {
// Copy original so don't modify it
let d = new Date(date);
let e = new Date(date);
e.setHours(23,59,59,999);
// Define methods
let end = {
second: d => d.setMilliseconds(999),
minute: d => d.setSeconds(59,999),
hour : d => d.setMinutes(59,59,999),
day : d => d.setHours(23,59,59,999),
week : w => {
w = startOf('week', w, weekStartDay);
w.setDate(w.getDate() + 6);
end.day(w);
d = w;
},
month : d => {
d.setMonth(d.getMonth() + 1, 0);
end.day(d);
},
year : d => {
d.setMonth(11, 31);
end.day(d);
},
decade: d => {
end.year(d);
let y = d.getFullYear();
d.setFullYear(y - y % 10 + 9);
},
century: d => {
end.year(d);
let y = d.getFullYear();
d.setFullYear(y - y % 100 + 99);
},
millenium: d => {
end.year(d);
let y = d.getFullYear();
d.setFullYear(y - y % 1000 + 999);
}
}
end[unit](d);
return d;
}
// Examples
let d = new Date();
['second','minute','hour','day','week','month','year',
'decade','century','millenium'].forEach(unit => {
console.log(('Start of ' + unit).padEnd(18) + ': ' +
startOf(unit, d).toString());
console.log(('End of ' + unit).padEnd(18) + ': ' +
endOf(unit, d).toString());
});
var currentDate = new Date();
var firstday = new Date(currentDate.setDate(currentDate.getDate() - currentDate.getDay())).toUTCString();
var lastday = new Date(currentDate.setDate(currentDate.getDate() - currentDate.getDay() + 7)).toUTCString();
console.log(firstday, lastday)
I'm using the following code in but because of .toUTCString() i'm receiving the following error as show in image.
if i remove .toUTCString(). output which i receive is not as expected
Small change to #SHIVA's answer which is a changed #Chris Lang answer.
For monday first usage with fix when today is sunday.
Date.prototype.GetFirstDayOfWeek = function() {
return (new Date(this.setDate(this.getDate() - this.getDay()+ (this.getDay() == 0 ? -6:1) )));
}
Date.prototype.GetLastDayOfWeek = function() {
return new Date(this.setDate(this.getDate() - (this.getDay() == 0 ? 7 : this.getDay()) + 7));
}
var today = new Date();
alert(today.GetFirstDayOfWeek());
alert(today.GetLastDayOfWeek());
You can try the below one too
let weekBgnDt = new Date();
let weekEndDt = new Date();
let wBeginDateLng, wEndDateLng, diffDays,dateCols=[];
if (weekBgnDt.getDay() > 0) {
diffDays = 0 - weekBgnDt.getDay();
weekBgnDt.setDate(weekBgnDt.getDate() + diffDays)
}
weekEndDt = weekEndDt.setDate(weekBgnDt.getDate() + 6)
wBeginDate = new Intl.DateTimeFormat('en-GB', { day: 'numeric', year: 'numeric',
month: '2-digit' }).format(weekBgnDt);
wEndDate = new Intl.DateTimeFormat('en-GB', { day: 'numeric', year: 'numeric', month:
'2-digit' }).format(weekEndDt);
wBeginDateLng = new Intl.DateTimeFormat('en-GB', { day: 'numeric', year: 'numeric',
month: 'long' }).format(weekBgnDt);
wEndDateLng = new Intl.DateTimeFormat('en-GB', { day: 'numeric', year: 'numeric',
month: 'long' }).format(weekEndDt);
console.log(wBeginDate, "-", wBeginDateLng)
console.log(wEndDate, "-", wEndDateLng)
for(let i=weekBgnDt;i<=weekEndDt;){
dateCols.push(new Intl.DateTimeFormat('en-GB', { day: 'numeric', year: 'numeric',
month: '2-digit' }).format(i));
i=weekBgnDt.setDate(weekBgnDt.getDate()+1)
}
console.log({wBeginDate,wBeginDateLng,wEndDate,wEndDateLng,dateCols})
The result will be printed as
{ wBeginDate: "16/05/2021", wBeginDateLng: "16 May 2021", wEndDate: "22/05/2021", wEndDateLng: "22 May 2021", dateCols: Array ["16/05/2021", "17/05/2021", "18/05/2021", "19/05/2021", "20/05/2021", "21/05/2021", "22/05/2021"] }
The right way to get the first and last date of the current week with appropriate month & year is as below
const curr = new Date();
const first = curr.getDate() - curr.getDay() + 1; // Start from Monday
const firstDate = new Date(curr.setDate(first));
const lastDate = new Date(curr.setDate(firstDate.getDate() + 6));
console.log(firstDate.toLocaleDateString(), lastDate.toLocaleDateString());
You can use this function, it works with first and last day of the week in different months or years
const getFirstAndLastDayOfTheWeek = () => {
// The starting time is the same current
let a = new Date();
let b = new Date();
const weekDay = a.getDay();
if (weekDay === 0) {
a.setDate(a.getDate() - 6);
} else if (weekDay === 1) {
b.setDate(b.getDate() + 7 - b.getDay());
} else if (weekDay >= 1) {
a.setDate(a.getDate() - a.getDay() + 1);
b.setDate(b.getDate() + 7 - b.getDay());
}
return { firstWeekDate: a, lastWeekDate: b };
}
console.log(getFirstAndLastDayOfTheWeek());

How can I get the 4 Mondays of a month with js?

I'm building a chart where the x-axis should be the four weeks of a month. I would like to display only the four Mondays of that month.
I already have the currentMonth and the currentYear variables, and I know how to get the first day of the month. All I need is to get the four Mondays of a month in an array. And all of this in the same JavaScript file.
I'm pretty lost within my programming logic, and I've seen plenty of solutions that don't fit my use case.
Right now, I have:
var date = new Date();
var currentYear = date.getFullYear();
var currentMonth = date.getMonth();
var firstDayofMonth = new Date(currentYear, currentMonth, 1);
var firstWeekDay = firstDayofMonth.getDay();
but I would like to have something like this:
var myDates = [
new Date(firstMonday),
new Date(secondMonday),
new Date(thirdMonday),
new Date(fourthMonday),
];
The following function will return all Mondays for the current month:
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;
}
This would return the fourth last monday of month [m] in year [y]
function lastmonday(y,m) {
var dat = new Date(y+'/'+m+'/1')
,currentmonth = m
,firstmonday = false;
while (currentmonth === m){
firstmonday = dat.getDay() === 1 || firstmonday;
dat.setDate(dat.getDate()+(firstmonday ? 7 : 1));
currentmonth = dat.getMonth()+1;
}
dat.setDate(dat.getDate()-7);
return dat;
}
// usage
lastmonday(2012,3); //=>Mon Mar 26 2012 00:00:00 GMT+0200
lastmonday(2012,2) //=>Mon Feb 27 2012 00:00:00 GMT+0100
lastmonday(1997,1) //=>Mon Jan 27 1997 00:00:00 GMT+0100
lastmonday(2012,4) //=>Mon Apr 30 2012 00:00:00 GMT+0200
To be more generic, this will deliver the last any weekday of a month:
function lastDayOfMonth(y,m,dy) {
var days = {sun:0,mon:1,tue:2,wed:3,thu:4,fri:5,sat:6}
,dat = new Date(y+'/'+m+'/1')
,currentmonth = m
,firstday = false;
while (currentmonth === m){
firstday = dat.getDay() === days[dy] || firstday;
dat.setDate(dat.getDate()+(firstday ? 7 : 1));
currentmonth = dat.getMonth()+1 ;
}
dat.setDate(dat.getDate()-7);
return dat;
}
// usage
lastDayOfMonth(2012,2,'tue'); //=>Tue Feb 28 2012 00:00:00 GMT+0100
lastDayOfMonth(1943,5,'fri'); //=>Fri May 28 1943 00:00:00 GMT+0200
For whoever may need, this is a general function to get every monday, tuesday, etc
getDatesOfDayOfWeek (year, month, dayOfWeek) {
const initialDate = new Date(year, month, 1);
const datesOfDayOfWeek = [];
while (initialDate.getDay() !== dayOfWeek) {
initialDate.setDate(initialDate.getDate() + 1);
}
while (initialDate.getMonth() === month) {
const nextDate = new Date(initialDate.getTime());
datesOfDayOfWeek.push(nextDate.getDate());
initialDate.setDate(initialDate.getDate() + 7);
}
return datesOfDayOfWeek;
}
I took Jake's code and generalized it to get the next N occurrences of a particular schedule. (e.g. "Get me the next 10 instances of 2nd Mondays and 1st and 3rd Wednesdays.")
schedule is an object with keys for day-of-week whose values are
an array of the incident within a month that the DoW falls.
keys can include numbers from 1-5, and -1 for "last."
items in a value array can include numbers from 0-6, where 0 is Sunday.
count is optional (defaults to 6) and represents how many items to show.
Samples
First and third Mondays would be nextNthMdays({1: [1, 3]})
Second Wed and Fri would be nextNthMdays({3: [2], 5: [2]})
Last Thursdays would be nextNthMdays({4: [-1]})
function nextNthMdays(schedule, count) {
var d = new Date(),
month = 999,
nthInMonth,
dates = [];
if (count == undefined) {
count = 6;
}
// start at the beginning of the month
d.setDate(1);
// Iterate until we have enough
while (dates.length < count) {
var day = d.getDay();
// Reset counters each month
if (d.getMonth() !== month) {
month = d.getMonth();
nthInMonth = Object.keys(schedule).reduce(function (obj, x) {
obj[x] = 0;
return obj;
}, {});
}
// When you reach an interesting weekday
if (day in schedule) {
// Increment its counter
nthInMonth[day]++;
// If it's after today
if (d > new Date()) {
// and its counter matches
if (schedule[day].indexOf(nthInMonth[day]) !== -1) {
// Add it
dates.push(new Date(d.getTime()));
}
// or if we want the last one
else if (schedule[day].indexOf(-1) !== -1) {
// verify that 7 days from then is a different month
var sevenAway = new Date(d);
sevenAway.setDate(sevenAway.getDate() + 7);
if (d.getMonth() !== sevenAway.getMonth()) {
// Add it
dates.push(new Date(d.getTime()));
}
}
}
}
// Move on to the next day
d.setDate(d.getDate() + 1);
}
return dates;
}
Demonstration
Expand the snippet to run some examples.
// `schedule` is an object with keys
// for day-of-week whose values are
// an array of the incident within
// a month that the DoW falls.
//
// keys can include numbers from
// 1-5, and -1 for "last."
// items in a value array can include
// numbers from 0-6, where 0 is
// Sunday.
//
// `count` is optional (defaults to 6)
// and represents how many items to
// show.
//
// First and third Mondays would be
// nextNthMdays({1: [1, 3]})
// Second Wed and Fri would be
// nextNthMdays({3: [2], 5: [2]})
// Last Thursdays would be
// nextNthMdays(4: [-1])
function nextNthMdays(schedule, count) {
var d = new Date(),
month = 999,
nthInMonth,
dates = [];
if (count == undefined) {
count = 6;
}
// start at the beginning of the month
d.setDate(1);
// Iterate until we have enough
while (dates.length < count) {
var day = d.getDay();
// Reset counters each month
if (d.getMonth() !== month) {
month = d.getMonth();
nthInMonth = Object.keys(schedule).reduce(function (obj, x) {
obj[x] = 0;
return obj;
}, {});
}
// When you reach an interesting weekday
if (day in schedule) {
// Increment its counter
nthInMonth[day]++;
// If it's after today
if (d > new Date()) {
// and its counter matches
if (schedule[day].indexOf(nthInMonth[day]) !== -1) {
// Add it
dates.push(new Date(d.getTime()));
}
// or if we want the last one
else if (schedule[day].indexOf(-1) !== -1) {
// verify that 7 days from then is a different month
var sevenAway = new Date(d);
sevenAway.setDate(sevenAway.getDate() + 7);
if (d.getMonth() !== sevenAway.getMonth()) {
// Add it
dates.push(new Date(d.getTime()));
}
}
}
}
// Move on to the next day
d.setDate(d.getDate() + 1);
}
return dates;
}
console.log('Next third Wednesdays');
console.log(nextNthMdays({3: [3],}));
console.log('Next first and third Mondays');
console.log(nextNthMdays({1: [1, 3],}, 4));
console.log('Next second Wed/Fridays');
console.log(nextNthMdays({3: [2], 5: [2],}, 3));
console.log('Next "Last Thursdays of the month"');
console.log(nextNthMdays({4: [-1],}, 3));

JavaScript function to add X months to a date

I’m looking for the easiest, cleanest way to add X months to a JavaScript date.
I’d rather not handle the rolling over of the year or have to write my own function.
Is there something built in that can do this?
The following function adds months to a date in JavaScript (source). It takes into account year roll-overs and varying month lengths:
function addMonths(date, months) {
var d = date.getDate();
date.setMonth(date.getMonth() + +months);
if (date.getDate() != d) {
date.setDate(0);
}
return date;
}
// Add 12 months to 29 Feb 2016 -> 28 Feb 2017
console.log(addMonths(new Date(2016,1,29),12).toString());
// Subtract 1 month from 1 Jan 2017 -> 1 Dec 2016
console.log(addMonths(new Date(2017,0,1),-1).toString());
// Subtract 2 months from 31 Jan 2017 -> 30 Nov 2016
console.log(addMonths(new Date(2017,0,31),-2).toString());
// Add 2 months to 31 Dec 2016 -> 28 Feb 2017
console.log(addMonths(new Date(2016,11,31),2).toString());
The above solution covers the edge case of moving from a month with a greater number of days than the destination month. eg.
Add twelve months to February 29th 2020 (should be February 28th 2021)
Add one month to August 31st 2020 (should be September 30th 2020)
If the day of the month changes when applying setMonth, then we know we have overflowed into the following month due to a difference in month length. In this case, we use setDate(0) to move back to the last day of the previous month.
Note: this version of this answer replaces an earlier version (below) that did not gracefully handle different month lengths.
var x = 12; //or whatever offset
var CurrentDate = new Date();
console.log("Current date:", CurrentDate);
CurrentDate.setMonth(CurrentDate.getMonth() + x);
console.log("Date after " + x + " months:", CurrentDate);
I'm using moment.js library for date-time manipulations.
Sample code to add one month:
var startDate = new Date(...);
var endDateMoment = moment(startDate); // moment(...) can also be used to parse dates in string format
endDateMoment.add(1, 'months');
This function handles edge cases and is fast:
function addMonthsUTC (date, count) {
if (date && count) {
var m, d = (date = new Date(+date)).getUTCDate()
date.setUTCMonth(date.getUTCMonth() + count, 1)
m = date.getUTCMonth()
date.setUTCDate(d)
if (date.getUTCMonth() !== m) date.setUTCDate(0)
}
return date
}
test:
> d = new Date('2016-01-31T00:00:00Z');
Sat Jan 30 2016 18:00:00 GMT-0600 (CST)
> d = addMonthsUTC(d, 1);
Sun Feb 28 2016 18:00:00 GMT-0600 (CST)
> d = addMonthsUTC(d, 1);
Mon Mar 28 2016 18:00:00 GMT-0600 (CST)
> d.toISOString()
"2016-03-29T00:00:00.000Z"
Update for non-UTC dates: (by A.Hatchkins)
function addMonths (date, count) {
if (date && count) {
var m, d = (date = new Date(+date)).getDate()
date.setMonth(date.getMonth() + count, 1)
m = date.getMonth()
date.setDate(d)
if (date.getMonth() !== m) date.setDate(0)
}
return date
}
test:
> d = new Date(2016,0,31);
Sun Jan 31 2016 00:00:00 GMT-0600 (CST)
> d = addMonths(d, 1);
Mon Feb 29 2016 00:00:00 GMT-0600 (CST)
> d = addMonths(d, 1);
Tue Mar 29 2016 00:00:00 GMT-0600 (CST)
> d.toISOString()
"2016-03-29T06:00:00.000Z"
Taken from #bmpsini and #Jazaret responses, but not extending prototypes: using plain functions (Why is extending native objects a bad practice?):
function isLeapYear(year) {
return (((year % 4 === 0) && (year % 100 !== 0)) || (year % 400 === 0));
}
function getDaysInMonth(year, month) {
return [31, (isLeapYear(year) ? 29 : 28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month];
}
function addMonths(date, value) {
var d = new Date(date),
n = date.getDate();
d.setDate(1);
d.setMonth(d.getMonth() + value);
d.setDate(Math.min(n, getDaysInMonth(d.getFullYear(), d.getMonth())));
return d;
}
Use it:
var nextMonth = addMonths(new Date(), 1);
Considering none of these answers will account for the current year when the month changes, you can find one I made below which should handle it:
The method:
Date.prototype.addMonths = function (m) {
var d = new Date(this);
var years = Math.floor(m / 12);
var months = m - (years * 12);
if (years) d.setFullYear(d.getFullYear() + years);
if (months) d.setMonth(d.getMonth() + months);
return d;
}
Usage:
return new Date().addMonths(2);
From the answers above, the only one that handles the edge cases (bmpasini's from datejs library) has an issue:
var date = new Date("03/31/2015");
var newDate = date.addMonths(1);
console.log(newDate);
// VM223:4 Thu Apr 30 2015 00:00:00 GMT+0200 (CEST)
ok, but:
newDate.toISOString()
//"2015-04-29T22:00:00.000Z"
worse :
var date = new Date("01/01/2015");
var newDate = date.addMonths(3);
console.log(newDate);
//VM208:4 Wed Apr 01 2015 00:00:00 GMT+0200 (CEST)
newDate.toISOString()
//"2015-03-31T22:00:00.000Z"
This is due to the time not being set, thus reverting to 00:00:00, which then can glitch to previous day due to timezone or time-saving changes or whatever...
Here's my proposed solution, which does not have that problem, and is also, I think, more elegant in that it does not rely on hard-coded values.
/**
* #param isoDate {string} in ISO 8601 format e.g. 2015-12-31
* #param numberMonths {number} e.g. 1, 2, 3...
* #returns {string} in ISO 8601 format e.g. 2015-12-31
*/
function addMonths (isoDate, numberMonths) {
var dateObject = new Date(isoDate),
day = dateObject.getDate(); // returns day of the month number
// avoid date calculation errors
dateObject.setHours(20);
// add months and set date to last day of the correct month
dateObject.setMonth(dateObject.getMonth() + numberMonths + 1, 0);
// set day number to min of either the original one or last day of month
dateObject.setDate(Math.min(day, dateObject.getDate()));
return dateObject.toISOString().split('T')[0];
};
Unit tested successfully with:
function assertEqual(a,b) {
return a === b;
}
console.log(
assertEqual(addMonths('2015-01-01', 1), '2015-02-01'),
assertEqual(addMonths('2015-01-01', 2), '2015-03-01'),
assertEqual(addMonths('2015-01-01', 3), '2015-04-01'),
assertEqual(addMonths('2015-01-01', 4), '2015-05-01'),
assertEqual(addMonths('2015-01-15', 1), '2015-02-15'),
assertEqual(addMonths('2015-01-31', 1), '2015-02-28'),
assertEqual(addMonths('2016-01-31', 1), '2016-02-29'),
assertEqual(addMonths('2015-01-01', 11), '2015-12-01'),
assertEqual(addMonths('2015-01-01', 12), '2016-01-01'),
assertEqual(addMonths('2015-01-01', 24), '2017-01-01'),
assertEqual(addMonths('2015-02-28', 12), '2016-02-28'),
assertEqual(addMonths('2015-03-01', 12), '2016-03-01'),
assertEqual(addMonths('2016-02-29', 12), '2017-02-28')
);
d = new Date();
alert(d.getMonth()+1);
Months have a 0-based index, it should alert(4) which is 5 (may);
Simple solution: 2678400000 is 31 day in milliseconds
var oneMonthFromNow = new Date((+new Date) + 2678400000);
Update:
Use this data to build our own function:
2678400000 - 31 day
2592000000 - 30 days
2505600000 - 29 days
2419200000 - 28 days
As most of the answers highlighted, we could use setMonth() method together with getMonth() method to add specific number of months to a given date.
Example: (as mentioned by #ChadD in his answer. )
var x = 12; //or whatever offset
var CurrentDate = new Date();
CurrentDate.setMonth(CurrentDate.getMonth() + x);
But we should carefully use this solution as we will get trouble with edge cases.
To handle edge cases, answer which is given in following link is helpful.
https://stackoverflow.com/a/13633692/3668866
Just to add on to the accepted answer and the comments.
var x = 12; //or whatever offset
var CurrentDate = new Date();
//For the very rare cases like the end of a month
//eg. May 30th - 3 months will give you March instead of February
var date = CurrentDate.getDate();
CurrentDate.setDate(1);
CurrentDate.setMonth(CurrentDate.getMonth()+X);
CurrentDate.setDate(date);
I wrote this alternative solution which works fine to me. It is useful when you wish calculate the end of a contract. For example, start=2016-01-15, months=6, end=2016-7-14 (i.e. last day - 1):
<script>
function daysInMonth(year, month)
{
return new Date(year, month + 1, 0).getDate();
}
function addMonths(date, months)
{
var target_month = date.getMonth() + months;
var year = date.getFullYear() + parseInt(target_month / 12);
var month = target_month % 12;
var day = date.getDate();
var last_day = daysInMonth(year, month);
if (day > last_day)
{
day = last_day;
}
var new_date = new Date(year, month, day);
return new_date;
}
var endDate = addMonths(startDate, months);
</script>
Examples:
addMonths(new Date("2016-01-01"), 1); // 2016-01-31
addMonths(new Date("2016-01-01"), 2); // 2016-02-29 (2016 is a leap year)
addMonths(new Date("2016-01-01"), 13); // 2017-01-31
addMonths(new Date("2016-01-01"), 14); // 2017-02-28
This works for all edge cases. The weird calculation for newMonth handles negative months input. If the new month does not match the expected month (like 31 Feb), it will set the day of month to 0, which translates to "end of previous month":
function dateAddCalendarMonths(date, months) {
monthSum = date.getMonth() + months;
newMonth = (12 + (monthSum % 12)) % 12;
newYear = date.getFullYear() + Math.floor(monthSum / 12);
newDate = new Date(newYear, newMonth, date.getDate());
return (newDate.getMonth() != newMonth)
? new Date(newDate.setDate(0))
: newDate;
}
I changed the accepted answer a bit to keep the original date intact, as I think it should in a function like this.
function addMonths(date, months) {
let newDate = new Date(date);
var day = newDate.getDate();
newDate.setMonth(newDate.getMonth() + +months);
if (newDate.getDate() != day)
newDate.setDate(0);
return newDate;
}
The following is an example of how to calculate a future date based on date input (membershipssignup_date) + added months (membershipsmonths) via form fields.
The membershipsmonths field has a default value of 0
Trigger link (can be an onchange event attached to membership term field):
Calculate Expiry Date
function calculateMshipExp() {
var calcval = null;
var start_date = document.getElementById("membershipssignup_date").value;
var term = document.getElementById("membershipsmonths").value; // Is text value
var set_start = start_date.split('/');
var day = set_start[0];
var month = (set_start[1] - 1); // January is 0 so August (8th month) is 7
var year = set_start[2];
var datetime = new Date(year, month, day);
var newmonth = (month + parseInt(term)); // Must convert term to integer
var newdate = datetime.setMonth(newmonth);
newdate = new Date(newdate);
//alert(newdate);
day = newdate.getDate();
month = newdate.getMonth() + 1;
year = newdate.getFullYear();
// This is British date format. See below for US.
calcval = (((day <= 9) ? "0" + day : day) + "/" + ((month <= 9) ? "0" + month : month) + "/" + year);
// mm/dd/yyyy
calcval = (((month <= 9) ? "0" + month : month) + "/" + ((day <= 9) ? "0" + day : day) + "/" + year);
// Displays the new date in a <span id="memexp">[Date]</span> // Note: Must contain a value to replace eg. [Date]
document.getElementById("memexp").firstChild.data = calcval;
// Stores the new date in a <input type="hidden" id="membershipsexpiry_date" value="" name="membershipsexpiry_date"> for submission to database table
document.getElementById("membershipsexpiry_date").value = calcval;
}
Sometimes useful create date by one operator like in BIRT parameters
I made 1 month back with:
new Date(new Date().setMonth(new Date().getMonth()-1));
As demonstrated by many of the complicated, ugly answers presented, Dates and Times can be a nightmare for programmers using any language. My approach is to convert dates and 'delta t' values into Epoch Time (in ms), perform any arithmetic, then convert back to "human time."
// Given a number of days, return a Date object
// that many days in the future.
function getFutureDate( days ) {
// Convert 'days' to milliseconds
var millies = 1000 * 60 * 60 * 24 * days;
// Get the current date/time
var todaysDate = new Date();
// Get 'todaysDate' as Epoch Time, then add 'days' number of mSecs to it
var futureMillies = todaysDate.getTime() + millies;
// Use the Epoch time of the targeted future date to create
// a new Date object, and then return it.
return new Date( futureMillies );
}
// Use case: get a Date that's 60 days from now.
var twoMonthsOut = getFutureDate( 60 );
This was written for a slightly different use case, but you should be able to easily adapt it for related tasks.
EDIT: Full source here!
Easiest solution is:
const todayDate = Date.now();
return new Date(todayDate + 1000 * 60 * 60 * 24 * 30* X);
where X is the number of months we want to add.
Easy, simplest
function addMonths(date, months) {date.setMonth(date.getMonth() + months); return date;};
Use it as
alert(new Date().toLocaleString()); //will say today
alert(addMonths(new Date(),12).toLocaleString()); //will say next year, same day and month
Looking for something in typescript?
export const addMonths = (inputDate: Date | string, monthsToAdd: number): Date => {
const date = new Date(inputDate);
if (!monthsToAdd) {
return date;
}
const dayOfMonth = date.getDate();
const endOfDesiredMonth = new Date(date.getTime());
endOfDesiredMonth.setMonth(date.getMonth() + monthsToAdd + 1, 0);
const daysInMonth = endOfDesiredMonth.getDate();
if (dayOfMonth >= daysInMonth) {
return endOfDesiredMonth;
} else {
date.setFullYear(endOfDesiredMonth.getFullYear(), endOfDesiredMonth.getMonth(), dayOfMonth);
return date;
}
}
A simple answer can be :
function addMonthsToDate(date, numMonths){
// Add months
date.setMonth(date.getMonth() + numMonths);
// Zero the time component
date.setHours(0, 0, 0, 0);
return date;
}
This can be called - to add two months:
console.log(addMonthsToDate(new Date(),2));
addDateMonate : function( pDatum, pAnzahlMonate )
{
if ( pDatum === undefined )
{
return undefined;
}
if ( pAnzahlMonate === undefined )
{
return pDatum;
}
var vv = new Date();
var jahr = pDatum.getFullYear();
var monat = pDatum.getMonth() + 1;
var tag = pDatum.getDate();
var add_monate_total = Math.abs( Number( pAnzahlMonate ) );
var add_jahre = Number( Math.floor( add_monate_total / 12.0 ) );
var add_monate_rest = Number( add_monate_total - ( add_jahre * 12.0 ) );
if ( Number( pAnzahlMonate ) > 0 )
{
jahr += add_jahre;
monat += add_monate_rest;
if ( monat > 12 )
{
jahr += 1;
monat -= 12;
}
}
else if ( Number( pAnzahlMonate ) < 0 )
{
jahr -= add_jahre;
monat -= add_monate_rest;
if ( monat <= 0 )
{
jahr = jahr - 1;
monat = 12 + monat;
}
}
if ( ( Number( monat ) === 2 ) && ( Number( tag ) === 29 ) )
{
if ( ( ( Number( jahr ) % 400 ) === 0 ) || ( ( Number( jahr ) % 100 ) > 0 ) && ( ( Number( jahr ) % 4 ) === 0 ) )
{
tag = 29;
}
else
{
tag = 28;
}
}
return new Date( jahr, monat - 1, tag );
}
testAddMonate : function( pDatum , pAnzahlMonate )
{
var datum_js = fkDatum.getDateAusTTMMJJJJ( pDatum );
var ergebnis = fkDatum.addDateMonate( datum_js, pAnzahlMonate );
app.log( "addDateMonate( \"" + pDatum + "\", " + pAnzahlMonate + " ) = \"" + fkDatum.getStringAusDate( ergebnis ) + "\"" );
},
test1 : function()
{
app.testAddMonate( "15.06.2010", 10 );
app.testAddMonate( "15.06.2010", -10 );
app.testAddMonate( "15.06.2010", 37 );
app.testAddMonate( "15.06.2010", -37 );
app.testAddMonate( "15.06.2010", 1234 );
app.testAddMonate( "15.06.2010", -1234 );
app.testAddMonate( "15.06.2010", 5620 );
app.testAddMonate( "15.06.2010", -5120 );
}
All these seem way too complicated and I guess it gets into a debate about what exactly adding "a month" means. Does it mean 30 days? Does it mean from the 1st to the 1st? From the last day to the last day?
If the latter, then adding a month to Feb 27th gets you to March 27th, but adding a month to Feb 28th gets you to March 31st (except in leap years, where it gets you to March 28th). Then subtracting a month from March 30th gets you... Feb 27th? Who knows...
For those looking for a simple solution, just add milliseconds and be done.
function getDatePlusDays(dt, days) {
return new Date(dt.getTime() + (days * 86400000));
}
or
Date.prototype.addDays = function(days) {
this = new Date(this.getTime() + (days * 86400000));
};
I have done by using Moment Js Library
Refs: https://momentjs.com/
startDate = new Date()
endDate = moment(startDate).add(2, "Months").format("YYYY-MM-DD")
endDate= new Date (endDate)
var a=new Date();
a.setDate(a.getDate()+5);
As above stated method, you can add month to Date function.

Categories