Related
I'm trying to write a script to subtract 5 days from a defined date but seems not working, here's my code:
var End_Day = sheet.getRange(i + 2, 20).getValue();
Logger.log(End_Day);
var End_day_2 = new Date();
End_day_2.setDate(End_Day.getDate()-5);
Logger.log(End_day_2);
and the result is not just - 5 days:
11:18:47 AM Info Sat Jun 04 00:00:00 GMT+08:00 2022
11:18:47 AM Info Fri Apr 29 11:18:47 GMT+08:00 2022
I am quite confused why the date move from Jun to Apr.
Thanks for having a look
Try:
var End_Day = sheet.getRange(i + 2, 20).getValue();
var End_day_2 = new Date(End_Day.getTime() - (5 * (1000 * 60 * 60 * 24)))
Logger.log(End_Day);
Logger.log(End_day_2);
Function:
const endDay = sheet.getRange(i + 2, 20).getValue()
const endDay2 = DateFromDaysAgo(endDay, 5)
...
function DateFromDaysAgo(startDate, number) {
if (typeof startDate === `string`) { startDate = new Date(startDate) }
return new Date(startDate.getTime() - (number * (1000 * 60 * 60 * 24)))
}
You should learn more about Date.prototype.setDate().It only changes the day of the month of a given Date instance.
As the code you posted, the day of the month of End_Day is 4, End_day_2.setDate(4 - 5) equals to End_day_2.setDate(-1) and the month of End_day_2 is April according to the console result, because there're 30 days in April, setDate(-1) means setDate(29), so you got Apr 29 at the end. That's how it goes.
One right way to do is substracting 5 days worth of milliseconds.
function addDays(date, days){
const DAY_IN_MILLISECONDS = 24 * 60 * 60000;
return new Date(date.getTime() + days * DAY_IN_MILLISECONDS);
}
console.log(addDays(new Date(), -5).toString()); // 5 days ago
I am quite confused why the date move from Jun to Apr.
It's because you're setting date on today(End_day_2) and not on your predefined date(End_day).
Change
End_day_2.setDate(End_Day.getDate()-5);
to
End_Day.setDate(End_Day.getDate()-5);
console.info(End_Day);
If what's coming from the sheet is a string, you will have to convert the date string into a date object.
The other thing is you have to work in milliseconds as #vanowm says:
606024*5 = 432000 * 1000 = 432000000
so skipping the sheet entirely:
x = new Date
> Fri May 27 2022 11:24:01 GMT-0400 (Eastern Daylight Time)
y = new Date(x - 432000000)
> Sun May 22 2022 11:24:01 GMT-0400 (Eastern Daylight Time)
This will do the trick. Works with any date and can subtract any number of days
const subtractDays = (fromDate, numDays) => {
if (!(fromDate instanceof Date)) throw 'The first argument must be a date';
return new Date(new Date().setDate(fromDate.getDate() - +numDays));
};
Weekago
function weekago() {
let dt = new Date();
dt.setDate(dt.getDate()-7);
Logger.log(dt);
return dt;
}
Five days ago
function fiveago() {
let dt = new Date();
dt.setDate(dt.getDate()-5)
Logger.log(dt);
return dt;
}
Five days from a date in a spreadsheet cell
function fivefromadateinspreadsheet() {
const v = SpreadsheetApp.getActiveSheet().getRange("A1").getValue();
let dt = new Date(v);
dt.setDate(dt.getDate()-5);//Note that does not return a date it return the numbrer of milliseconds
Logger.log(dt);
return dt;
}
You can subtract 5 days from a defined date in Google App Script by using the Utilities.formatDate() method. Here's an example:
function subtractDays() {
var date = new Date();
var subtractDays = 5;
// Subtract 5 days from the current date
date.setDate(date.getDate() - subtractDays);
// Format the new date
var newDate = Utilities.formatDate(date, "UTC", "yyyy-MM-dd");
Logger.log(newDate);
}
In this example, we first create a Date object to represent the current date. Then, we subtract 5 days from the current date by using the setDate() method. Finally, we format the new date using the Utilities.formatDate() method and log it to the console using the Logger.log() method.
You can modify the subtractDays variable to subtract a different number of days from the date, or you can use a different date object to start with.
I'm trying to get the millisecond value of the nearest absolute year in JavaScript, replying only on the valueOf() method of the JavaScript Date object.
For example: today is Monday April 4th 2016 at 12:50am. So I am looking for the nearest absolute year (in the past). January 1st, 2016, 00:00am.
Here is the code I have:
var ms_per_year = 31536000000;
var now = new Date().valueOf();
var mod_year = now % ms_per_year;
var nearest_absolute_year = now - mod_year;
console.log(new Date(nearest_absolute_year));
// Sun Dec 20 2015 19:00:00 GMT-0500 (EST)
console.log(new Date(Date.parse('2016 1 1 00:00:00')));
// Fri Jan 01 2016 00:00:00 GMT-0500 (EST)
I would expect the two printed dates to be the same, as they are with minutes:
var ms_per_minute = 60 * 1000;
var now = new Date().valueOf();
var mod_minute = now % ms_per_minute;
var nearest_absolute_minute = now - mod_minute;
console.log(new Date(nearest_absolute_minute));
// Mon Apr 04 2016 00:57:00 GMT-0400 (EDT)
console.log(new Date(Date.parse('2016 4 4 00:57:00')));
// Mon Apr 04 2016 00:57:00 GMT-0400 (EDT)
How can I calculate the milliseconds passed since 1970 and the beginning of the current year with without using Date.parse(), relying solely on math?
You need to deal with leap years, Himanshu is on the track for an elegant solution, a simple loop will do the trick but is not so efficient:
/* #returns {number} time value for start of current year
** Don't use Date methods
** Assumes current time is after epoch (1970-01-01T00:00:00Z)
*/
function getStartOfYear(timeValue) {
var timeValue = timeValue || Date.now();
var accumulatedTime = 0;
var day = 8.64e7;
var year = 1970;
var msForYear = 365*day; // ms for 1970
function isLeap(n) {
return ((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0);
}
// Continue while adding ms for current year won't go past limit
while ((accumulatedTime + msForYear) < timeValue) {
// Add time for current year
accumulatedTime += msForYear;
// Calculate time for next year
msForYear = (isLeap(++year)? 366:365) * day;
}
// Return accumulated time
return accumulatedTime;
}
// Tests
['2010','2011','2012','2013','2014','2015','2016','2017'].forEach(function(y){
//Generate time value away from start of year
var startOfYear = new Date(getStartOfYear(new Date(y,3).getTime() + 23000));
document.write('<br>UTC start of year: ' + startOfYear.toISOString());
startOfYear.setMinutes(startOfYear.getMinutes() + startOfYear.getTimezoneOffset());
document.write('<br>Local start of year: ' + startOfYear);
});
body {
font-family: courier, mono-space;
font-size: 90%
}
Edit
Here is a non–looping solution. It works in UTC as above, but can be adjusted to local as suggested there too.
function getStartOfYear(timeValue) {
timeValue = +timeValue || Date.now();
// ms for one day
var day = 8.64e7;
// ms for standard year
var year = 365 * day
// ms for leap block
var leapBlock = year * 4 + day;
// Use 1969-01-01T00:00:00Z as epoch
timeValue += year;
// Accumulate time
var accumulatedTime = 0;
accumulatedTime += Math.floor(timeValue / leapBlock) * leapBlock;
accumulatedTime += Math.floor((timeValue % leapBlock) / year) * year;
// Reset epoch to 1970-01-01T00:00:00Z and return time value
return accumulatedTime - year;
}
And if you want obfuscated, but concise, code, try:
function getStartOfYear(timeValue) {
timeValue = +timeValue || Date.now();
var day = 8.64e7, year = 365 * day, leapBlock = year * 4 + day, accumulatedTime = 0;
return ((timeValue + year) / leapBlock | 0) * leapBlock + ((timeValue + year) % leapBlock / year | 0) * year - year;
}
This should do the trick:
var d = new Date(new Date().getFullYear(), 0);
d.valueOf(); // > 1451634391371 (ms)
You're logic is not working due to the following assumption
var ms_per_year = 31536000000
For a year with 365 days this is the correct value of milliseconds, but you forgot to take leaps years into account.
The following code will help
var ms_per_year = 31536000000;
var ms_per_day = 86400000;
var now = new Date().valueOf();
var mod_year = now % ms_per_year;
var year = Math.floor(now/ms_per_year);
var leap_years = Math.floor(year/4);
var nearest_absolute_year = now - mod_year;
var actual_value = nearest_absolute_year + (leap_years*ms_per_day);
console.log(new Date(actual_value));
correct me if you find any mistakes.
I have two sets of codes that work. Needed help combining them into one.
This code gets me the difference between two dates. works perfectly:
function test(){
var date1 = new Date(txtbox_1.value);
var date2 = new Date(txtbox_2.value);
var diff = (date2 - date1)/1000;
var diff = Math.abs(Math.floor(diff));
var days = Math.floor(diff/(24*60*60));
var leftSec = diff - days * 24*60*60;
var hrs = Math.floor(leftSec/(60*60));
var leftSec = leftSec - hrs * 60*60;
var min = Math.floor(leftSec/(60));
var leftSec = leftSec - min * 60;
txtbox_3.value = days + "." + hrs; }
source for the above code
The code below by #cyberfly appears to have the answer of excluding sat and sun which is what i needed. source. However, its in jquery and the above code is in JS. Therefore, needed help combining as i lacked that knowledge :(
<script type="text/javascript">
$("#startdate, #enddate").change(function() {
var d1 = $("#startdate").val();
var d2 = $("#enddate").val();
var minutes = 1000*60;
var hours = minutes*60;
var day = hours*24;
var startdate1 = getDateFromFormat(d1, "d-m-y");
var enddate1 = getDateFromFormat(d2, "d-m-y");
var days = calcBusinessDays(new Date(startdate1),new Date(enddate1));
if(days>0)
{ $("#noofdays").val(days);}
else
{ $("#noofdays").val(0);}
});
</script>
EDIT
Made an attempt at combining the codes. here is my sample. getting object expected error.
function test(){
var date1 = new Date(startdate.value);
var date2 = new Date(enddate.value);
var diff = (date2 - date1)/1000;
var diff = Math.abs(Math.floor(diff));
var days = Math.floor(diff/(24*60*60));
var leftSec = diff - days * 24*60*60;
var hrs = Math.floor(leftSec/(60*60));
var leftSec = leftSec - hrs * 60*60;
var min = Math.floor(leftSec/(60));
var leftSec = leftSec - min * 60;
var startdate1 = getDateFromFormat(startdate, "dd/mm/yyyy hh:mm");
var enddate1 = getDateFromFormat(enddate, "dd/mm/yyyy hh:mm");
days = calcBusinessDays(new Date(startdate1),new Date(enddate1));
noofdays.value = days + "." + hrs; }
start: <input type="text" id="startdate" name="startdate" value="02/03/2015 00:00">
end: <input type="text" id="enddate" name="enddate" value="02/03/2015 00:01">
<input type="text" id="noofdays" name="noofdays" value="">
When determining the number of days between two dates, there are lots of decisions to be made about what is a day. For example, the period 1 Feb to 2 Feb is generally one day, so 1 Feb to 1 Feb is zero days.
When adding the complexity of counting only business days, things get a lot tougher. E.g. Monday 2 Feb 2015 to Friday 6 February is 4 elapsed days (Monday to Tuesday is 1, Monday to Wednesday is 2, etc.), however the expression "Monday to Friday" is generally viewed as 5 business days and the duration Mon 2 Feb to Sat 7 Feb should also be 4 business days, but Sunday to Saturday should be 5.
So here's my algorithm:
Get the total number of whole days between the two dates
Divide by 7 to get the number of whole weeks
Multiply the number of weeks by two to get the number of weekend days
Subtract the number of weekend days from the whole to get business days
If the number of total days is not an even number of weeks, add the numbe of weeks * 7 to the start date to get a temp date
While the temp date is less than the end date:
if the temp date is not a Saturday or Sunday, add one the business days
add one to the temp date
That's it.
The stepping part at the end can probably be replaced by some other algorithm, but it will never loop for more than 6 days so it's a simple and reasonably efficient solution to the issue of uneven weeks.
Some consequences of the above:
Monday to Friday is 4 business days
Any day to the same day in a different week is an even number of weeks and therefore an even mutiple of 5, e.g. Monday 2 Feb to Monday 9 Feb and Sunday 1 Feb to Sunday 8 Feb are 5 business days
Friday 6 Feb to Sunday 7 Feb is zero business days
Friday 6 Feb to Monday 9 Feb is one business day
Sunday 8 Feb to: Sunday 15 Feb, Sat 14 Feb and Fri 13 Feb are all 5 business days
Here's the code:
// Expects start date to be before end date
// start and end are Date objects
function dateDifference(start, end) {
// Copy date objects so don't modify originals
var s = new Date(+start);
var e = new Date(+end);
// Set time to midday to avoid dalight saving and browser quirks
s.setHours(12,0,0,0);
e.setHours(12,0,0,0);
// Get the difference in whole days
var totalDays = Math.round((e - s) / 8.64e7);
// Get the difference in whole weeks
var wholeWeeks = totalDays / 7 | 0;
// Estimate business days as number of whole weeks * 5
var days = wholeWeeks * 5;
// If not even number of weeks, calc remaining weekend days
if (totalDays % 7) {
s.setDate(s.getDate() + wholeWeeks * 7);
while (s < e) {
s.setDate(s.getDate() + 1);
// If day isn't a Sunday or Saturday, add to business days
if (s.getDay() != 0 && s.getDay() != 6) {
++days;
}
}
}
return days;
}
I don't know how it compares to jfriend00's answer or the code you referenced, if you want the period to be inclusive, just add one if the start or end date are a business day.
Here's a simple function to calculate the number of business days between two date objects. As designed, it does not count the start day, but does count the end day so if you give it a date on a Tuesday of one week and a Tuesday of the next week, it will return 5 business days. This does not account for holidays, but does work properly across daylight savings changes.
function calcBusinessDays(start, end) {
// This makes no effort to account for holidays
// Counts end day, does not count start day
// make copies we can normalize without changing passed in objects
var start = new Date(start);
var end = new Date(end);
// initial total
var totalBusinessDays = 0;
// normalize both start and end to beginning of the day
start.setHours(0,0,0,0);
end.setHours(0,0,0,0);
var current = new Date(start);
current.setDate(current.getDate() + 1);
var day;
// loop through each day, checking
while (current <= end) {
day = current.getDay();
if (day >= 1 && day <= 5) {
++totalBusinessDays;
}
current.setDate(current.getDate() + 1);
}
return totalBusinessDays;
}
And, the jQuery + jQueryUI code for a demo:
// make both input fields into date pickers
$("#startDate, #endDate").datepicker();
// process click to calculate the difference between the two days
$("#calc").click(function(e) {
var diff = calcBusinessDays(
$("#startDate").datepicker("getDate"),
$("#endDate").datepicker("getDate")
);
$("#diff").html(diff);
});
And, here's a simple demo built with the date picker in jQueryUI: http://jsfiddle.net/jfriend00/z1txs10d/
const firstDate = new Date("December 30, 2020");
const secondDate = new Date("January 4, 2021");
const daysWithOutWeekEnd = [];
for (var currentDate = new Date(firstDate); currentDate <= secondDate; currentDate.setDate(currentDate.getDate() + 1)) {
// console.log(currentDate);
if (currentDate.getDay() != 0 && currentDate.getDay() != 6) {
daysWithOutWeekEnd.push(new Date(currentDate));
}
}
console.log(daysWithOutWeekEnd, daysWithOutWeekEnd.length);
#RobG has given an excellent algorithm to separate business days from weekends.
I think the only problem is if the starting days is a weekend, Saturday or Sunday, then the no of working days/weekends will one less.
Corrected code is below.
function dateDifference(start, end) {
// Copy date objects so don't modify originals
var s = new Date(start);
var e = new Date(end);
var addOneMoreDay = 0;
if( s.getDay() == 0 || s.getDay() == 6 ) {
addOneMoreDay = 1;
}
// Set time to midday to avoid dalight saving and browser quirks
s.setHours(12,0,0,0);
e.setHours(12,0,0,0);
// Get the difference in whole days
var totalDays = Math.round((e - s) / 8.64e7);
// Get the difference in whole weeks
var wholeWeeks = totalDays / 7 | 0;
// Estimate business days as number of whole weeks * 5
var days = wholeWeeks * 5;
// If not even number of weeks, calc remaining weekend days
if (totalDays % 7) {
s.setDate(s.getDate() + wholeWeeks * 7);
while (s < e) {
s.setDate(s.getDate() + 1);
// If day isn't a Sunday or Saturday, add to business days
if (s.getDay() != 0 && s.getDay() != 6) {
++days;
}
//s.setDate(s.getDate() + 1);
}
}
var weekEndDays = totalDays - days + addOneMoreDay;
return weekEndDays;
}
JSFiddle link is https://jsfiddle.net/ykxj4k09/2/
First Get the Number of Days in a month
totalDays(month, year) {
return new Date(year, month, 0).getDate();
}
Then Get No Of Working Days In A Month By removing Saturday and Sunday
totalWorkdays() {
var d = new Date(); // to know present date
var m = d.getMonth() + 1; // to know present month
var y = d.getFullYear(); // to knoow present year
var td = this.totalDays(m, y);// to get no of days in a month
for (var i = 1; i <= td; i++) {
var s = new Date(y, m - 1, i);
if (s.getDay() != 0 && s.getDay() != 6) {
this.workDays.push(s.getDate());// working days
}else {
this.totalWeekDays.push(s.getDate());//week days
}
}
this.totalWorkingDays = this.workDays.length;
}
I thought the above code snippets others shared are lengthy.
I am sharing a concise snippet that gives date after considering the total number of days specified. we can also customize dates other than Saturdays and Sundays.
function getBusinessDays(dateObj, days) {
for (var i = 0; i < days; i++) {
if (days > 0) {
switch (dateObj.getDay()) {
// 6 being Saturday and 0 being Sunday.
case 6, 0:
dateObj.setDate(dateObj.getDate() + 2)
break;
//5 = Friday.
case 5:
dateObj.setDate(dateObj.getDate() + 3)
break;
//handle Monday, Tuesday, Wednesday and Thursday!
default:
dateObj.setDate(dateObj.getDate() + 1)
//console.log(dateObj)
break;
}
}
}
return dateObj;
}
console.log(getBusinessDays(new Date(), 11))
//Mon Dec 20 2021 18:56:01 GMT+0530 (India Standard Time)
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.
Want to improve this post? Provide detailed answers to this question, including citations and an explanation of why your answer is correct. Answers without enough detail may be edited or deleted.
Is there an easy way of taking a olain JavaScript Date (e.g. today) and going back X days?
So, for example, if I want to calculate the date 5 days before today.
Try something like this:
var d = new Date();
d.setDate(d.getDate()-5);
Note that this modifies the date object and returns the time value of the updated date.
var d = new Date();
document.write('Today is: ' + d.toLocaleString());
d.setDate(d.getDate() - 5);
document.write('<br>5 days ago was: ' + d.toLocaleString());
var dateOffset = (24*60*60*1000) * 5; //5 days
var myDate = new Date();
myDate.setTime(myDate.getTime() - dateOffset);
If you're performing lots of headachy date manipulation throughout your web application, DateJS will make your life much easier:
http://simonwillison.net/2007/Dec/3/datejs/
It goes something like this:
var d = new Date(); // today!
var x = 5; // go back 5 days!
d.setDate(d.getDate() - x);
I noticed that the getDays+ X doesn't work over day/month boundaries. Using getTime works as long as your date is not before 1970.
var todayDate = new Date(), weekDate = new Date();
weekDate.setTime(todayDate.getTime()-(7*24*3600000));
If you want it all on one line instead.
5 days from today
//past
var fiveDaysAgo = new Date(new Date().setDate(new Date().getDate() - 5));
//future
var fiveDaysInTheFuture = new Date(new Date().setDate(new Date().getDate() + 5));
5 days from a specific date
var pastDate = new Date('2019-12-12T00:00:00');
//past
var fiveDaysAgo = new Date(new Date().setDate(pastDate.getDate() - 5));
//future
var fiveDaysInTheFuture = new Date(new Date().setDate(pastDate.getDate() + 5));
I wrote a function you can use.
function AddOrSubractDays(startingDate, number, add) {
if (add) {
return new Date(new Date().setDate(startingDate.getDate() + number));
} else {
return new Date(new Date().setDate(startingDate.getDate() - number));
}
}
console.log('Today : ' + new Date());
console.log('Future : ' + AddOrSubractDays(new Date(), 5, true));
console.log('Past : ' + AddOrSubractDays(new Date(), 5, false));
I find a problem with the getDate()/setDate() method is that it too easily turns everything into milliseconds, and the syntax is sometimes hard for me to follow.
Instead I like to work off the fact that 1 day = 86,400,000 milliseconds.
So, for your particular question:
today = new Date()
days = 86400000 //number of milliseconds in a day
fiveDaysAgo = new Date(today - (5*days))
Works like a charm.
I use this method all the time for doing rolling 30/60/365 day calculations.
You can easily extrapolate this to create units of time for months, years, etc.
get moment.js. All the cool kids use it. It has more formatting options, etc. Where
var n = 5;
var dateMnsFive = moment(<your date>).subtract(n , 'day');
Optional! Convert to JS Date obj for Angular binding.
var date = new Date(dateMnsFive.toISOString());
Optional! Format
var date = dateMnsFive.format("YYYY-MM-DD");
A few of the existing solutions were close, but not quite exactly what I wanted. This function works with both positive or negative values and handles boundary cases.
function addDays(date, days) {
return new Date(
date.getFullYear(),
date.getMonth(),
date.getDate() + days,
date.getHours(),
date.getMinutes(),
date.getSeconds(),
date.getMilliseconds()
);
}
Without using the second variable, you can replace 7 for with your back x days:
let d=new Date(new Date().getTime() - (7 * 24 * 60 * 60 * 1000))
I made this prototype for Date so that I could pass negative values to subtract days and positive values to add days.
if(!Date.prototype.adjustDate){
Date.prototype.adjustDate = function(days){
var date;
days = days || 0;
if(days === 0){
date = new Date( this.getTime() );
} else if(days > 0) {
date = new Date( this.getTime() );
date.setDate(date.getDate() + days);
} else {
date = new Date(
this.getFullYear(),
this.getMonth(),
this.getDate() - Math.abs(days),
this.getHours(),
this.getMinutes(),
this.getSeconds(),
this.getMilliseconds()
);
}
this.setTime(date.getTime());
return this;
};
}
So, to use it i can simply write:
var date_subtract = new Date().adjustDate(-4),
date_add = new Date().adjustDate(4);
I like doing the maths in milliseconds. So use Date.now()
var newDate = Date.now() + -5*24*3600*1000; // date 5 days ago in milliseconds
and if you like it formatted
new Date(newDate).toString(); // or .toUTCString or .toISOString ...
NOTE: Date.now() doesn't work in older browsers (eg IE8 I think). Polyfill here.
UPDATE June 2015
#socketpair pointed out my sloppiness. As s/he says "Some day in year have 23 hours, and some 25 due to timezone rules".
To expand on that, the answer above will have daylightsaving inaccuracies in the case where you want to calculate the LOCAL day 5 days ago in a timezone with daylightsaving changes and you
assume (wrongly) that Date.now() gives you the current LOCAL now time, or
use .toString() which returns the local date and therefore is incompatible with the Date.now() base date in UTC.
However, it works if you're doing your math all in UTC, eg
A. You want the UTC date 5 days ago from NOW (UTC)
var newDate = Date.now() + -5*24*3600*1000; // date 5 days ago in milliseconds UTC
new Date(newDate).toUTCString(); // or .toISOString(), BUT NOT toString
B. You start with a UTC base date other than "now", using Date.UTC()
newDate = new Date(Date.UTC(2015, 3, 1)).getTime() + -5*24*3600000;
new Date(newDate).toUTCString(); // or .toISOString BUT NOT toString
split your date into parts, then return a new Date with the adjusted values
function DateAdd(date, type, amount){
var y = date.getFullYear(),
m = date.getMonth(),
d = date.getDate();
if(type === 'y'){
y += amount;
};
if(type === 'm'){
m += amount;
};
if(type === 'd'){
d += amount;
};
return new Date(y, m, d);
}
Remember that the months are zero based, but the days are not. ie new Date(2009, 1, 1) == 01 February 2009, new Date(2009, 1, 0) == 31 January 2009;
Some people suggested using moment.js to make your life easier when handling dates in js. Time has passed since those answers and it is noteworthy, that the authors of moment.js now discourage its use. Mainly due to its size and lack of tree-shaking-support.
If you want to go the library route, use an alternative like Luxon. It is significantly smaller (because of its clever use of the Intl object and support for tree-shaking) and just as versatile as moment.js.
To go back 5 days from today in Luxon, you would do:
import { DateTime } from 'luxon'
DateTime.now().minus({ days: 5 });
function addDays (date, daysToAdd) {
var _24HoursInMilliseconds = 86400000;
return new Date(date.getTime() + daysToAdd * _24HoursInMilliseconds);
};
var now = new Date();
var yesterday = addDays(now, - 1);
var tomorrow = addDays(now, 1);
See the following code, subtract the days from the current date. Also, set the month according to substracted date.
var today = new Date();
var substract_no_of_days = 25;
today.setTime(today.getTime() - substract_no_of_days* 24 * 60 * 60 * 1000);
var substracted_date = (today.getMonth()+1) + "/" +today.getDate() + "/" + today.getFullYear();
alert(substracted_date);
I have created a function for date manipulation. you can add or subtract any number of days, hours, minutes.
function dateManipulation(date, days, hrs, mins, operator) {
date = new Date(date);
if (operator == "-") {
var durationInMs = (((24 * days) * 60) + (hrs * 60) + mins) * 60000;
var newDate = new Date(date.getTime() - durationInMs);
} else {
var durationInMs = (((24 * days) * 60) + (hrs * 60) + mins) * 60000;
var newDate = new Date(date.getTime() + durationInMs);
}
return newDate;
}
Now, call this function by passing parameters. For example, here is a function call for getting date before 3 days from today.
var today = new Date();
var newDate = dateManipulation(today, 3, 0, 0, "-");
Use MomentJS.
function getXDaysBeforeDate(referenceDate, x) {
return moment(referenceDate).subtract(x , 'day').format('MMMM Do YYYY, h:mm:ss a');
}
var yourDate = new Date(); // let's say today
var valueOfX = 7; // let's say 7 days before
console.log(getXDaysBeforeDate(yourDate, valueOfX));
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.2/moment.min.js"></script>
The top answers led to a bug in my code where on the first of the month it would set a future date in the current month. Here is what I did,
curDate = new Date(); // Took current date as an example
prvDate = new Date(0); // Date set to epoch 0
prvDate.setUTCMilliseconds((curDate - (5 * 24 * 60 * 60 * 1000))); //Set epoch time
I like the following because it is one line. Not perfect with DST changes but usually good enough for my needs.
var fiveDaysAgo = new Date(new Date() - (1000*60*60*24*5));
Using Modern JavaScript function syntax
const getDaysPastDate = (daysBefore, date = new Date) => new Date(date - (1000 * 60 * 60 * 24 * daysBefore));
console.log(getDaysPastDate(1)); // yesterday
A easy way to manage dates is use Moment.js
You can use add. Example
var startdate = "20.03.2014";
var new_date = moment(startdate, "DD.MM.YYYY");
new_date.add(5, 'days'); //Add 5 days to start date
alert(new_date);
Docs http://momentjs.com/docs/#/manipulating/add/
for me all the combinations worked fine with below code snipplet ,
the snippet is for Angular-2 implementation ,
if you need to add days , pass positive numberofDays , if you need to substract pass negative numberofDays
function addSubstractDays(date: Date, numberofDays: number): Date {
let d = new Date(date);
return new Date(
d.getFullYear(),
d.getMonth(),
(d.getDate() + numberofDays)
);
}
I get good mileage out of date.js:
http://www.datejs.com/
d = new Date();
d.add(-10).days(); // subtract 10 days
Nice!
Website includes this beauty:
Datejs doesn’t just parse strings, it slices them cleanly in two
If you want to both subtract a number of days and format your date in a human readable format, you should consider creating a custom DateHelper object that looks something like this :
var DateHelper = {
addDays : function(aDate, numberOfDays) {
aDate.setDate(aDate.getDate() + numberOfDays); // Add numberOfDays
return aDate; // Return the date
},
format : function format(date) {
return [
("0" + date.getDate()).slice(-2), // Get day and pad it with zeroes
("0" + (date.getMonth()+1)).slice(-2), // Get month and pad it with zeroes
date.getFullYear() // Get full year
].join('/'); // Glue the pieces together
}
}
// With this helper, you can now just use one line of readable code to :
// ---------------------------------------------------------------------
// 1. Get the current date
// 2. Subtract 5 days
// 3. Format it
// 4. Output it
// ---------------------------------------------------------------------
document.body.innerHTML = DateHelper.format(DateHelper.addDays(new Date(), -5));
(see also this Fiddle)
To calculate relative time stamps with a more precise difference than whole days, you can use Date.getTime() and Date.setTime() to work with integers representing the number of milliseconds since a certain epoch—namely, January 1, 1970. For example, if you want to know when it’s 17 hours after right now:
const msSinceEpoch = (new Date()).getTime();
const fortyEightHoursLater = new Date(msSinceEpoch + 48 * 60 * 60 * 1000).toLocaleString();
const fortyEightHoursEarlier = new Date(msSinceEpoch - 48 * 60 * 60 * 1000).toLocaleString();
const fiveDaysAgo = new Date(msSinceEpoch - 120 * 60 * 60 * 1000).toLocaleString();
console.log({msSinceEpoch, fortyEightHoursLater, fortyEightHoursEarlier, fiveDaysAgo})
reference
function daysSinceGivenDate (date) {
const dateInSeconds = Math.floor((new Date().valueOf() - date.valueOf()) / 1000);
const oneDayInSeconds = 86400;
return Math.floor(dateInSeconds / oneDayInSeconds); // casted to int
};
console.log(daysSinceGivenDate(new Date())); // 0
console.log(daysSinceGivenDate(new Date("January 1, 2022 03:24:00"))); // relative...
First arg is the date to start with and second is how mush day you want to increase or reduce to the date
example (1)- pass -1 to reduce date by one day
example (2)- pass 1 to increase date by one day
const EditDay = (date: Date, num: number): Date => {
return new Date(date.getTime() + num * 24 * 60 * 60 * 1000)
}
When setting the date, the date converts to milliseconds, so you need to convert it back to a date:
This method also take into consideration, new year change etc.
function addDays( date, days ) {
var dateInMs = date.setDate(date.getDate() - days);
return new Date(dateInMs);
}
var date_from = new Date();
var date_to = addDays( new Date(), parseInt(days) );
You can using Javascript.
var CurrDate = new Date(); // Current Date
var numberOfDays = 5;
var days = CurrDate.setDate(CurrDate.getDate() + numberOfDays);
alert(days); // It will print 5 days before today
For PHP,
$date = date('Y-m-d', strtotime("-5 days")); // it shows 5 days before today.
echo $date;
Hope it will help you.
I converted into millisecond and deducted days else month and year won't change and logical
var numberOfDays = 10;//number of days need to deducted or added
var date = "01-01-2018"// date need to change
var dt = new Date(parseInt(date.substring(6), 10), // Year
parseInt(date.substring(3,5), 10) - 1, // Month (0-11)
parseInt(date.substring(0,2), 10));
var new_dt = dt.setMilliseconds(dt.getMilliseconds() - numberOfDays*24*60*60*1000);
new_dt = new Date(new_dt);
var changed_date = new_dt.getDate()+"-"+(new_dt.getMonth()+1)+"-"+new_dt.getFullYear();
Hope helps