JavaScript function to add X months to a date - javascript

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.

Related

Find first monday date of month

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

How do get time only , date only and full date in javascript

How do get different form of date datetime and full date depending upon the scenarios.
1 In case date is newest less than 24 Hr old then I have to show like 22:31
In case date is of same month for e.g february but older than 24 hr then I have to show like 15 Feb.
In case date is older than a month then I have to show like 15 Feb 17.
Till now I have made two javascript function for the purpose .
function getLocalizeDateTime(dateString,format) {
if(dateString==null || dateString==undefined || dateString==""){
return "";
}
var dateTime = dateString.trim().split(" ");
var dateOnly = dateTime[0];
var timeOnly = dateTime[1];
timeOnlyOfDate = timeOnly;
var temp = dateOnly + "T" + timeOnly+"Z";
var utc_date =new Date(temp);
currentDateStr = dateString;
//var offset = new Date().getTimezoneOffset();
//utc_date.setMinutes(utc_date.getMinutes() - offset);
if(format!=undefined && format!=null)
return date2str(utc_date,format);
return date.toString();
}
function date2str(x, y) {
var z = {
YR: x.getFullYear(),
M: x.getMonth() + 1,
d: x.getDate(),
h: x.getHours(),
m: x.getMinutes(),
s: x.getSeconds()
};
// Here return 22:32 if date is less than 24 hr old.
// return 24 feb as currentmonth is feb.
// return 24 feb 17 in case current date is march or greater.
y = y.replace(/(M+|d+|h+|m+|s+)/g, function(v) {
return ((v.length > 1 ? "0" : "") + eval('z.' + v.slice(-1))).slice(-2)
});
return y.replace(/(y+)/g, function(v) {
return x.getFullYear().toString().slice(-v.length)
});
}
But these functions return whole date in format for e.g for date "2017-02-24 07:46:38" and format MM-dd-yyyy hh:mm" it is returning 02-24-2017 13:16. How do acheve above mentioned 3 business check.
If you can be sure of support for toLocaleString options, they can be used to format the date string. Otherwise, use a library, e.g.:
function formatTime(date) {
var now = new Date();
var timeOpt = {hour:'2-digit', hour12:false, minute:'2-digit'};
var monthOpt = {day:'numeric', month:'short'};
var fullOpt = {day:'numeric', month:'short', year:'2-digit'};
if (now - date < 8.64e7) {
return date.toLocaleString(undefined, timeOpt);
}
if (now.getFullYear() == date.getFullYear() &&
now.getMonth() == date.getMonth()) {
return date.toLocaleString(undefined, monthOpt);
}
return date.toLocaleString(undefined, fullOpt);
}
// Tests
var soon = new Date();
soon.setHours(soon.getHours() - 2, 23);
var sameMonth = new Date();
sameMonth.setHours(sameMonth.getHours() - 25);
var agesAgo = new Date(2016,5,6,14,27,50);
[soon, sameMonth, agesAgo].forEach(function(date){
console.log(formatTime(date));
})
The sameMonth test will use the fullOpt on the first of the month or before 01:00 on the second as it will set the date to the previous month, but otherwise it will show the more than a day but same month result.
This is my solution. Basically I just cut up the dates to perform conditional tests on them and then stitched them back together. The advantage is that it uses no libraries to do it.
I did grab the 'subtract one day' code from another answer [Link].
$(document).ready ( function() {
var less_than_24 = getLocalizeDateTime(new Date('Fri Feb 24 2017 10:41:28'));
var same_month = getLocalizeDateTime(new Date('Fri Feb 16 2017 13:41:28'));
var older_than_month = getLocalizeDateTime(new Date('Fri Jan 24 2017 13:41:28'));
console.log('less_than_24: ' + less_than_24);
console.log('same_month: ' + same_month);
console.log('older_than_month: ' + older_than_month);
});
function getLocalizeDateTime(dateString,format) {
var monthNames = ['Jan','Feb','Mar','Apr','May','Jun',
'Jul','Aug','Sep','Oct','Nov','Dec'];
if (dateString==null || dateString==undefined || dateString=="") {
return "";
}
var now = new Date();
var hours_24_ago = now;
hours_24_ago.setDate(hours_24_ago.getDate() - 1);
if (dateString >= hours_24_ago) {
return dateString.getHours() + ':' + dateString.getMinutes();
} else if (dateString.getFullYear() == now.getFullYear()
&& dateString.getMonth() == now.getMonth()) {
return (dateString.getDate() + ' ' + monthNames[dateString.getMonth()]);
} else {
return (dateString.getDate() + ' '
+ monthNames[dateString.getMonth()] + ' '
+ dateString.getFullYear());
}
}

How to calculate and check for a bi-weekly date

I really need your help,
Let's say my demarcation start date is: December 19, 2016 as defined by the variable x
How can I write a JavaScript function, such that it will check the present date against x and the present date against what the recurrence date will be (14) days from x as defined by the variable y.
var y = recurrence is every 14 days, thereafter from the date (x) with no end date specified (unlimited)
Ex.
function() {
if (present date == x) { alert(true) }
if (present date == y) { alert(true) }
}
You could get the number of days difference between your start date and the current date then check if that number is a multiple of 14.
function treatAsUTC(date) {
var result = new Date(date);
result.setMinutes(result.getMinutes() - result.getTimezoneOffset());
return result;
}
function daysBetween(startDate, endDate) {
var millisecondsPerDay = 24 * 60 * 60 * 1000;
return Math.floor((treatAsUTC(endDate) - treatAsUTC(startDate)) / millisecondsPerDay);
}
var demarcationdate = new Date("2016-12-19"),
today = new Date(),
days = daysBetween(demarcationdate,today),
daystill = 14 - days%14,
rec = days%14==0,
d = new Date();
d.setDate(today.getDate() + daystill);
var nextDate = (d.getDate() + "/" + (d.getMonth() + 1) + "/" + d.getFullYear());
console.log("Days diff = "+days+". Recurs today = "+rec+". Next in "+daystill+" days ("+nextDate.toString()+").");
jsFiddle
If Date.now() == 1482181410856, 14 days from now will be 1482181410856 + (14 * 24 * 60 * 60 * 1000) == 1483391010856.
let y = new Date(Date.now() + (14 * 24 * 60 * 60 * 1000));
console.log(y.toUTCString()); // "Mon, 02 Jan 2017 21:03:30 GMT"
Assuming you really want to compare precise dates, i.e. to the milliseconds, then:
var present_date = new Date();
if(present_date.getTime() === x.getTime()) alert("Today is the same date as x");
else {
var y = new Date(x.getTime());
y.setDate(y.getDate() + 14); // add 14 days
if(present_date.getTime() === y.getTime()) alert("Today is the same date as y");
}
But most of the time we want to compare dates as full days, not milliseconds, so you'd have to compare ranges instead (from midnight to 11:59PM)... In that case, I recommend using a library to make your life easier - like moment.js for instance...
Hope this helps!
This is probably a duplicate of Add +1 to current date.
If you have a start date, say 20 December, 2016, you can calculate 14 days after that by simply adding 14 days to the date. You can then check if today's date is either of those dates, e.g.
// Create a Date for 20 December, 2016 with time 00:00:00
var startDate = new Date(2016,11,20);
// Create a Date for the start + 14 days with time 00:00:00
var startPlus14 = new Date(startDate);
startPlus14.setDate(startPlus14.getDate() + 14);
// Get today and set the time to 00:00:00.000
var today = new Date();
today.setHours(0,0,0,0);
if (+today == +startDate) {
console.log('Today is the start date');
} else if (+today == +startPlus14) {
console.log('Today is 14 days after the start date');
} else {
console.log('Today is neither the start nor 14 days after the start');
}

Find previous year in JavaScript using only Date.valueOf()

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.

Incrementing a date in JavaScript

I need to increment a date value by one day in JavaScript.
For example, I have a date value 2010-09-11 and I need to store the date of the next day in a JavaScript variable.
How can I increment a date by a day?
Three options for you:
1. Using just JavaScript's Date object (no libraries):
My previous answer for #1 was wrong (it added 24 hours, failing to account for transitions to and from daylight saving time; Clever Human pointed out that it would fail with November 7, 2010 in the Eastern timezone). Instead, Jigar's answer is the correct way to do this without a library:
// To do it in local time
var tomorrow = new Date();
tomorrow.setDate(tomorrow.getDate() + 1);
// To do it in UTC
var tomorrow = new Date();
tomorrow.setUTCDate(tomorrow.getUTCDate() + 1);
This works even for the last day of a month (or year), because the JavaScript date object is smart about rollover:
// (local time)
var lastDayOf2015 = new Date(2015, 11, 31);
console.log("Last day of 2015: " + lastDayOf2015.toISOString());
var nextDay = new Date(+lastDayOf2015);
var dateValue = nextDay.getDate() + 1;
console.log("Setting the 'date' part to " + dateValue);
nextDay.setDate(dateValue);
console.log("Resulting date: " + nextDay.toISOString());
2. Using MomentJS:
var today = moment();
var tomorrow = moment(today).add(1, 'days');
(Beware that add modifies the instance you call it on, rather than returning a new instance, so today.add(1, 'days') would modify today. That's why we start with a cloning op on var tomorrow = ....)
3. Using DateJS, but it hasn't been updated in a long time:
var today = new Date(); // Or Date.today()
var tomorrow = today.add(1).day();
var myDate = new Date();
//add a day to the date
myDate.setDate(myDate.getDate() + 1);
The easiest way is to convert to milliseconds and add 1000*60*60*24 milliseconds e.g.:
var tomorrow = new Date(today.getTime()+1000*60*60*24);
Tomorrow in one line in pure JS but it's ugly !
new Date(new Date().setDate(new Date().getDate() + 1))
Here is the result :
Thu Oct 12 2017 08:53:30 GMT+0200 (Romance Summer Time)
None of the examples in this answer seem to work with Daylight Saving Time adjustment days. On those days, the number of hours in a day are not 24 (they are 23 or 25, depending on if you are "springing forward" or "falling back".)
The below AddDays javascript function accounts for daylight saving time:
function addDays(date, amount) {
var tzOff = date.getTimezoneOffset() * 60 * 1000,
t = date.getTime(),
d = new Date(),
tzOff2;
t += (1000 * 60 * 60 * 24) * amount;
d.setTime(t);
tzOff2 = d.getTimezoneOffset() * 60 * 1000;
if (tzOff != tzOff2) {
var diff = tzOff2 - tzOff;
t += diff;
d.setTime(t);
}
return d;
}
Here are the tests I used to test the function:
var d = new Date(2010,10,7);
var d2 = AddDays(d, 1);
document.write(d.toString() + "<br />" + d2.toString());
d = new Date(2010,10,8);
d2 = AddDays(d, -1)
document.write("<hr /><br />" + d.toString() + "<br />" + d2.toString());
d = new Date('Sun Mar 27 2011 01:59:00 GMT+0100 (CET)');
d2 = AddDays(d, 1)
document.write("<hr /><br />" + d.toString() + "<br />" + d2.toString());
d = new Date('Sun Mar 28 2011 01:59:00 GMT+0100 (CET)');
d2 = AddDays(d, -1)
document.write("<hr /><br />" + d.toString() + "<br />" + d2.toString());
You first need to parse your string before following the other people's suggestion:
var dateString = "2010-09-11";
var myDate = new Date(dateString);
//add a day to the date
myDate.setDate(myDate.getDate() + 1);
If you want it back in the same format again you will have to do that "manually":
var y = myDate.getFullYear(),
m = myDate.getMonth() + 1, // january is month 0 in javascript
d = myDate.getDate();
var pad = function(val) { var str = val.toString(); return (str.length < 2) ? "0" + str : str};
dateString = [y, pad(m), pad(d)].join("-");
But I suggest getting Date.js as mentioned in other replies, that will help you alot.
I feel that nothing is safer than .getTime() and .setTime(), so this should be the best, and performant as well.
const d = new Date()
console.log(d.setTime(d.getTime() + 1000 * 60 * 60 * 24)) // MILLISECONDS
.setDate() for invalid Date (like 31 + 1) is too dangerous, and it depends on the browser implementation.
Getting the next 5 days:
var date = new Date(),
d = date.getDate(),
m = date.getMonth(),
y = date.getFullYear();
for(i=0; i < 5; i++){
var curdate = new Date(y, m, d+i)
console.log(curdate)
}
Two methods:
1:
var a = new Date()
// no_of_days is an integer value
var b = new Date(a.setTime(a.getTime() + no_of_days * 86400000)
2: Similar to the previous method
var a = new Date()
// no_of_days is an integer value
var b = new Date(a.setDate(a.getDate() + no_of_days)
Via native JS, to add one day you may do following:
let date = new Date(); // today
date.setDate(date.getDate() + 1) // tomorrow
Another option is to use moment library:
const date = moment().add(14, "days").toDate()
Get the string value of the date using the dateObj.toJSON() method Ref: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toJSON
Slice the date from the returned value and then increment by the number of days you want.
var currentdate = new Date();
currentdate.setDate(currentdate.getDate() + 1);
var tomorrow = currentdate.toJSON().slice(0,10);
Date.prototype.AddDays = function (days) {
days = parseInt(days, 10);
return new Date(this.valueOf() + 1000 * 60 * 60 * 24 * days);
}
Example
var dt = new Date();
console.log(dt.AddDays(-30));
console.log(dt.AddDays(-10));
console.log(dt.AddDays(-1));
console.log(dt.AddDays(0));
console.log(dt.AddDays(1));
console.log(dt.AddDays(10));
console.log(dt.AddDays(30));
Result
2017-09-03T15:01:37.213Z
2017-09-23T15:01:37.213Z
2017-10-02T15:01:37.213Z
2017-10-03T15:01:37.213Z
2017-10-04T15:01:37.213Z
2017-10-13T15:01:37.213Z
2017-11-02T15:01:37.213Z
Not entirelly sure if it is a BUG(Tested Firefox 32.0.3 and Chrome 38.0.2125.101), but the following code will fail on Brazil (-3 GMT):
Date.prototype.shiftDays = function(days){
days = parseInt(days, 10);
this.setDate(this.getDate() + days);
return this;
}
$date = new Date(2014, 9, 16,0,1,1);
$date.shiftDays(1);
console.log($date+"");
$date.shiftDays(1);
console.log($date+"");
$date.shiftDays(1);
console.log($date+"");
$date.shiftDays(1);
console.log($date+"");
Result:
Fri Oct 17 2014 00:01:01 GMT-0300
Sat Oct 18 2014 00:01:01 GMT-0300
Sat Oct 18 2014 23:01:01 GMT-0300
Sun Oct 19 2014 23:01:01 GMT-0200
Adding one Hour to the date, will make it work perfectly (but does not solve the problem).
$date = new Date(2014, 9, 16,0,1,1);
Result:
Fri Oct 17 2014 01:01:01 GMT-0300
Sat Oct 18 2014 01:01:01 GMT-0300
Sun Oct 19 2014 01:01:01 GMT-0200
Mon Oct 20 2014 01:01:01 GMT-0200
Results in a string representation of tomorrow's date. Use new Date() to get today's date, adding one day using Date.getDate() and Date.setDate(), and converting the Date object to a string.
const tomorrow = () => {
let t = new Date();
t.setDate(t.getDate() + 1);
return `${t.getFullYear()}-${String(t.getMonth() + 1).padStart(2, '0')}-${String(
t.getDate()
).padStart(2, '0')}`;
};
tomorrow();
Incrementing date's year with vanilla js:
start_date_value = "01/01/2019"
var next_year = new Date(start_date_value);
next_year.setYear(next_year.getYear() + 1);
console.log(next_year.getYear()); //=> 2020
Just in case someone wants to increment other value than the date (day)
Timezone/daylight savings aware date increment for JavaScript dates:
function nextDay(date) {
const sign = v => (v < 0 ? -1 : +1);
const result = new Date(date.getTime());
result.setDate(result.getDate() + 1);
const offset = result.getTimezoneOffset();
return new Date(result.getTime() + sign(offset) * offset * 60 * 1000);
}
This a simpler method ,
and it will return the date in simple yyyy-mm-dd format , Here it is
function incDay(date, n) {
var fudate = new Date(new Date(date).setDate(new Date(date).getDate() + n));
fudate = fudate.getFullYear() + '-' + (fudate.getMonth() + 1) + '-' + fudate.toDateString().substring(8, 10);
return fudate;
}
example :
var tomorrow = incDay(new Date(), 1); // the next day of today , aka tomorrow :) .
var spicaldate = incDay("2020-11-12", 1); // return "2020-11-13" .
var somedate = incDay("2020-10-28", 5); // return "2020-11-02" .
Note
incDay(new Date("2020-11-12"), 1);
incDay("2020-11-12", 1);
will return the same result .
Use this function, it´s solved my problem:
let nextDate = (daysAhead:number) => {
const today = new Date().toLocaleDateString().split('/')
const invalidDate = new Date(`${today[2]}/${today[1]}/${Number(today[0])+daysAhead}`)
if(Number(today[1]) === Number(12)){
return new Date(`${Number(today[2])+1}/${1}/${1}`)
}
if(String(invalidDate) === 'Invalid Date'){
return new Date(`${today[2]}/${Number(today[1])+1}/${1}`)
}
return new Date(`${today[2]}/${Number(today[1])}/${Number(today[0])+daysAhead}`)
}
Assigning the Increment of current date to other Variable
let startDate=new Date();
let endDate=new Date();
endDate.setDate(startDate.getDate() + 1)
console.log(startDate,endDate)

Categories