Javascript: setDate(DATE + day) not update month - javascript

I created this function to increment a date (for a jQuery UI Datepicker):
function addDay(date) {
var moreDay = new Date();
var decomposed = date.split("-");
var act = new Date(decomposed[2], decomposed[1], decomposed[0]);
moreDay.setDate(act.getDate()+1);
return moreDay;
}
So, it scomposes the date (ex: 12-06-2013 (dd-mm-YYYY)) and put the values into a new Date, after that it addes a day. It works, but the month not change. Example, I changed the function into this:
function addDay() {
var moreDay = new Date();
var act = new Date(2013, 7, 3);
moreDay.setDate(act.getDate()+1);
alert(moreDay);
}
And it returns Jun 4th 2013.. How it's possible?

I think I see what's the trouble.
function addDay() {
var moreDay = new Date();
var act = new Date(2013, 7, 3);
moreDay.setDate(act.getDate()+1);
alert(moreDay);
}
And it returns Jun 4th 2013.. How it's possible?
Some points you must consider:
The creation of the date new Date(2013, 7, 3) does not create the date 03/Jul/2013:
Months are zero-based, meaning they go from 0 to 11, not 1 to 12.
This way, the month 7 actually is August.
The statement moreDay.setDate(act.getDate()+1) does not make moreDay the date act plus one day. Because:
date.getDate() returns the day of the month of the date variable
date.setDate(int) sets the day of date (just the day, leaving the year and month intact)
What the statement moreDay.setDate(act.getDate()+1) does then is:
Set moreDay's day the value of act's day plus one.
In other words, as moreDay's value is new Date() (which is the current day - right now 11/Jun/2013 where I live), and act's day is 3, the statement evaluation then really is:
Step #1: moreDay.setDate( act.getDate() + 1 );
Step #2: moreDay.setDate( (03/Aug/2013).getDate() + 1 );
Step #3: moreDay.setDate( 03 + 1 );
Step #4: moreDay.setDate( 4 );
Step #5: (11/Jun/2013).setDate( 4 );
Step #6: (04/Jun/2013)
Thus ending Jun 4th 2013.

It's not clear what you want to do with your function. If you want to take a date and add a day, try with this:
function addDay(date) {
var decomposed = date.split("-"),
moreDay = new Date(decomposed[2], decomposed[1] - 1, decomposed[0]);
moreDay.setDate(moreDay.getDate() + 1);
alert(moreDay);
}
Please take note that in common dd-mm-yyyy dates, January is 1, whereas to define a Date object January is 0, hence the - 1.
This alternative should be faster than setDate:
moreDay.setTime(moreDay.getTime() + 864e5);
Or you could define your Date object directly with an added day:
moreDay = new Date(decomposed[2], decomposed[1] - 1, +decomposed[0] + 1);

moreDay.setDate(act.getDate()+1);
This will only add one day. Why do you expect it to add a month, too?
If you want to add a month also, try this:
function addDay() {
var moreDay = new Date();
var act = new Date(2013, 7, 3);
moreDay.setMonth(act.getMonth()+1); // add one month
moreDay.setDate(act.getDate()+1); // add one day
alert(moreDay);
}

One way to do this:
var now = new Date();
function addDays(date,days) {
var currentDate = date.getDate();
date.setDate(currentDate + days);
alert(date);
}
addDays(now,14)

Related

How to reliably get previous month from js Date?

What's the better way to get the previous month from a given day in vanilla javascript?
A quick search would tell you to do:
const getPreviousMonth = date => {
const clone = new Date(date.getTime())
clone.setMonth(date.getMonth() - 1)
return clone
}
The problem being getPreviousDate(new Date(2021, 4, 31)) returns May 1st, not April 30, which seems to imply it just subtracts 30 days. Curiously, getPreviousDate(new Date(2021, 2, 1)) correctly return Feb 1st instead of a late date in January, so the 30 days theory is a dud.
Given that, is there a best practice vanilla solution to getPrevious month? Currently, I add a line like: if (date.getDate() === 31) newDate.setDate(-1) which returns April 29 (!?). So I'm sure a better solutions exists.
PS.: Just to be clear, I don't want to know what date it was 30 days ago, but what month was the previous month. So to May 31 the answer is April, to March 1, it is February.
Edit: Specifically, I want to return a Date object within the previous month, preferably on the last day.
Just use clone.setDate(0) and you will get the last day of previous month
const dates = [new Date(2021,0,15), new Date(2021,2,31)]
const getPreviousMonth = date => {
const clone = new Date(date)
clone.setDate(0)
return clone
}
dates.forEach(d=>{
console.log(getPreviousMonth(d))
})
Is that what you are looking for:
now = new Date();
if (now.getMonth() == 0) {
var current = new Date(now.getFullYear() - 1, 11, 1);
} else {
var current = new Date(now.getFullYear(), now.getMonth());
}
console.log(current);

Get the most recently occurring Sunday

I need to display the current week in a calendar view, starting from Sunday.
What's the safest way to determine "last sunday" in Javascript?
I was calculating it using the following code:
Date.prototype.addDays = function(n) {
return new Date(this.getTime() + (24*60*60*1000)*n);
}
var today = new Date(now.getFullYear(), now.getMonth(), now.getDate());
var lastSunday = today.addDays(0-today.getDay());
This code makes the assumption that every day consists of twenty four hours. This is correct, EXCEPT if it's a daylight savings crossover day, in which case the day could be twenty-three or twenty-five hours.
This week, In Sydney, Australia, we set our clocks forward an hour. As a result, my code calculates lastSunday as 23:00 on Saturday.
So what IS the safest and most efficient way to determine last Sunday?
To safely add exactly one day, use:
d.setDate(d.getDate() + 1);
which is daylight saving safe. To set a date object to the last Sunday:
function setToLastSunday(d) {
return d.setDate(d.getDate() - d.getDay());
}
Or to return a new Date object for last Sunday:
function getLastSunday(d) {
var t = new Date(d);
t.setDate(t.getDate() - t.getDay());
return t;
}
Edit
The original answer had an incorrect version adding time, that does add one day but not how the OP wants.
Try this jsfiddle
It uses only built in date methods
var now = new Date();
var today = new Date(now.getFullYear(), now.getMonth(), now.getDate());
var lastSunday = new Date(today.setDate(today.getDate()-today.getDay()));
using date-fn library: previousSunday(date)
const now = new Date(); // the date to start counting from
previousSunday(now);
Docs: https://date-fns.org/v2.25.0/docs/previousSunday

Simple javascript date math... not really

I am trying to create a simple script that gives me the next recycling date based on a biweekly schedule starting on Wed Jul 6, 2011. So I've created this simple function...
function getNextDate(startDate) {
if (today <= startDate) {
return startDate;
}
// calculate the day since the start date.
var totalDays = Math.ceil((today.getTime()-startDate.getTime())/(one_day));
// check to see if this day falls on a recycle day
var bumpDays = totalDays%14; // mod 14 -- pickup up every 14 days...
// pickup is today
if (bumpDays == 0) {
return today;
}
// return the closest day which is in 14 days, less the # of days since the last
// pick up..
var ms = today.getTime() + ((14- bumpDays) * one_day);
return new Date(ms);
}
and can call it like...
var today=new Date();
var one_day=1000*60*60*24; // one day in milliseconds
var nextDate = getNextDate(new Date(2011,06,06));
so far so good... but when I project "today" to 10/27/2011, I get Tuesday 11/8/2011 as the next date instead of Wednesday 11/9/2011... In fact every day from now thru 10/26/2011 projects the correct pick-up... and every date from 10/27/2011 thru 2/28/2012 projects the Tuesday and not the Wednesday. And then every date from 2/29/2012 (leap year) thru 10/24/2012 (hmmm October again) projects the Wednesday correctly. What am I missing? Any help would be greatly appreciated..
V
The easiest way to do this is update the Date object using setDate. As the comments for this answer indicate this isn't officially part of the spec, but it is supported on all major browsers.
You should NEVER update a different Date object than the one you did the original getDate call on.
Sample implementation:
var incrementDate = function (date, amount) {
var tmpDate = new Date(date);
tmpDate.setDate(tmpDate.getDate() + amount)
return tmpDate;
};
If you're trying to increment a date, please use this function. It will accept both positive and negative values. It also guarantees that the used date objects isn't changed. This should prevent any error which can occur if you don't expect the update to change the value of the object.
Incorrect usage:
var startDate = new Date('2013-11-01T11:00:00');
var a = new Date();
a.setDate(startDate.getDate() + 14)
This will update the "date" value for startDate with 14 days based on the value of a. Because the value of a is not the same is the previously defined startDate it's possible to get a wrong value.
Expanding on Exellian's answer, if you want to calculate any period in the future (in my case, for the next pay date), you can do a simple loop:
var today = new Date();
var basePayDate = new Date(2012, 9, 23, 0, 0, 0, 0);
while (basePayDate < today) {
basePayDate.setDate(basePayDate.getDate()+14);
}
var nextPayDate = new Date(basePayDate.getTime());
basePayDate.setDate(nextPayDate.getDate()-14);
document.writeln("<p>Previous pay Date: " + basePayDate.toString());
document.writeln("<p>Current Date: " + today.toString());
document.writeln("<p>Next pay Date: " + nextPayDate.toString());
This won't hit odd problems, assuming the core date services work as expected. I have to admit, I didn't test it out to many years into the future...
Note: I had a similar issue; I wanted to create an array of dates on a weekly basis, ie., start date 10/23/2011 and go for 12 weeks. My code was more or less this:
var myDate = new Date(Date.parse(document.eventForm.startDate.value));
var toDate = new Date(myDate);
var week = 60 * 60 * 24 * 7 * 1000;
var milliseconds = toDate.getTime();
dateArray[0] = myDate.format('m/d/Y');
for (var count = 1; count < numberOccurrences; count++) {
milliseconds += week;
toDate.setTime(milliseconds);
dateArray[count] = toDate.format('m/d/Y');
}
Because I didn't specify the time and I live in the US, my default time was midnight, so when I crossed the daylight savings time border, I moved into the previous day. Yuck. I resolved it by setting my time of day to noon before I did my week calculation.

Get a date object (six months prior) from another date object

How can I create a date object which is less than n number of months from another date object? I am looking for something like DateAdd().
Example:
var objCurrentDate = new Date();
Now using objCurrentDate, how can I create a Date object having a date which is six months older than today's date / objCurrentDate?
You can implement very easily an "addMonths" function:
function addMonths(date, months) {
date.setMonth(date.getMonth() + months);
return date;
}
addMonths(new Date(), -6); // six months before now
// Thu Apr 30 2009 01:22:46 GMT-0600
addMonths(new Date(), -12); // a year before now
// Thu Oct 30 2008 01:20:22 GMT-0600
EDIT: As reported by #Brien, there were several problems with the above approach. It wasn't handling correctly the dates where, for example, the original day in the input date is higher than the number of days in the target month.
Another thing I disliked is that the function was mutating the input Date object.
Here's a better implementation handling the edge cases of the end of months and this one doesn't cause any side-effects in the input date supplied:
const getDaysInMonth = (year, month) => new Date(year, month, 0).getDate()
const addMonths = (input, months) => {
const date = new Date(input)
date.setDate(1)
date.setMonth(date.getMonth() + months)
date.setDate(Math.min(input.getDate(), getDaysInMonth(date.getFullYear(), date.getMonth()+1)))
return date
}
console.log(addMonths(new Date('2020-01-31T00:00:00'), -6))
// "2019-07-31T06:00:00.000Z"
console.log(addMonths(new Date('2020-01-31T00:00:00'), 1))
// "2020-02-29T06:00:00.000Z"
console.log(addMonths(new Date('2020-05-31T00:00:00'), -6))
// "2019-11-30T06:00:00.000Z"
console.log(addMonths(new Date('2020-02-29T00:00:00'), -12))
// "2019-02-28T06:00:00.000Z"
Create date object and pass the value of n, where n is number(add/sub) of month.
var dateObj = new Date();
var requiredDate= dateObj.setMonth(dateObj.getMonth() - n);
var oldDate:Date = new Date();
/*
Check and adjust the date -
At the least, make sure that the getDate() returns a
valid date for the calculated month and year.
If it's not valid, change the date as per your needs.
You might want to reset it to 1st day of the month/last day of the month
or change the month and set it to 1st day of next month or whatever.
*/
if(oldDate.getMonth() < n)
oldDate.setFullYear(oldDate.getFullYear() - 1);
oldDate.setMonth((oldDate.getMonth() + n) % 12);
You have to be careful because dates have a lot of edge cases. For example, merely changing the month back by 6 doesn't account for the differing number of days in each month. For example, if you run a function like:
function addMonths(date, months) {
date.setMonth((date.getMonth() + months) % 12);
return date;
}
addMonths(new Date(2020, 7, 31), -6); //months are 0 based so 7 = August
The resulting date to return would be February 31st, 2020. You need to account for differences in the number of days in a month. Other answers have suggested this in various ways, by moving it to the first of the month, or the last of the month, or the first of the next month, etc. Another way to handle it is to keep the date if it is valid, or to move it to the end of the month if it overflows the month's regular dates. You could write this like:
function addMonths(date, months) {
var month = (date.getMonth() + months) % 12;
//create a new Date object that gets the last day of the desired month
var last = new Date(date.getFullYear(), month + 1, 0);
//compare dates and set appropriately
if (date.getDate() <= last.getDate()) {
date.setMonth(month);
}
else {
date.setMonth(month, last.getDate());
}
return date;
}
This at least ensures that the selected day won't "overflow" the month that it is being moved to. Finding the last day of the month with the datePart = 0 method is documented here.
This function still leaves a lot to be desired, as it doesn't add years and you can't subtract more than a year (or you will run into a new issue with negatives being involved). However, fixing those and the other issues you may run into (namely timezones) will be left as an exercise for the reader.

Find first day of previous month in javascript

Given a date object, how to get its previous month's first day in javascript
function firstDayInPreviousMonth(yourDate) {
var d = new Date(yourDate);
d.setDate(1);
d.setMonth(d.getMonth() - 1);
return d;
}
EDIT: Alright... I've definitely learned something here. I think that this is the simplest solution that covers all cases (and yes, it does work for January):
function firstDayInPreviousMonth(yourDate) {
return new Date(yourDate.getFullYear(), yourDate.getMonth() - 1, 1);
}
The following should work:
now = new Date();
if (now.getMonth() == 0) {
current = new Date(now.getFullYear() - 1, 11, 1);
} else {
current = new Date(now.getFullYear(), now.getMonth() - 1, 1);
}
keeping in mind that months are zero-based so December is 11 rather than 12.
But, as others have pointed out, the month wraps, even as part of the atomic constructor, so the following is also possible:
now = new Date();
firstDayPrevMonth = new Date(now.getFullYear(), now.getMonth() - 1, 1);
I like this solution. It might not be the briefest, but it highlights some functions of the setDate() method on Date() objects that not everybody will be familiar with:
function firstDayPreviousMonth(originalDate) {
var d = new Date(originalDate);
d.setDate(0); // set to last day of previous month
d.setDate(1); // set to the first day of that month
return d;
}
It makes use of the fact that .setDate(0) will change the date to point to the last day of the previous month, while .setDate(1) will change it (further) to point to the first day of that month. It lets the core Javascript libs do the heavy lifting.
You can see a working Plunk here.
It will help to get the previous month first and last date.
function getLastMonth(){
var now = new Date();
var lastday = new Date(now.getFullYear(), now.getMonth(), 0);
var firstday = new Date(lastday.getFullYear(), lastday.getMonth(), 1);
var lastMonth = firstday.getDate()+'/'+(firstday.getMonth()+1)+'/'+firstday.getFullYear()+' - '+lastday.getDate()+'/'+(firstday.getMonth()+1)+'/'+lastday.getFullYear();
return lastMonth;
}
Why reinventing the wheel?
Use moment.js or one of the alternatives (Luxon, Day.js, etc.):
moment().subtract(1, "months").startOf("months").toDate().
I've needed to use the begging of the month in a BootStrap Min month and didn't want to write it all out.
(() => new Date(new Date().getFullYear(), new Date().getMonth(),1, 0))()

Categories