This question already has answers here:
`date.setMonth` causes the month to be set too high if `date` is at the end of the month
(8 answers)
Closed 5 years ago.
Please someone tell me why the month gets increased by 1 if its value is higher than 9. The code is below
var dd = new Date();
dd.setFullYear(2017);
dd.setMonth(7);
console.log("Month(Expecting 7, and received 7) = " + dd.getMonth());
dd.setMonth(10);
console.log("Month(Expecting 10, and received 11) = " + dd.getMonth());
Fiddler code at here - https://jsfiddle.net/vzmtp3ua/
Because 31 days do not exist in every month so the extra days are added to the next month.
Set Date as Oct 31, add a month so it would be November 31st since there are 30 days the date is moved to December 1st.
In some months there are less days then 31 , So extra days are added to the following month
It has to do with the number of days in that month making the date shift to the first day in the next month.
The documentation mentions this: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/setMonth
The current day of month will have an impact on the behaviour of this method. Conceptually it will add the number of days given by the current day of the month to the 1st day of the new month specified as the parameter, to return the new date. For example, if the current value is 31st August 2016, calling setMonth with a value of 1 will return 2nd March 2016. This is because in 2016 February had 29 days.
Not all the months have same number of days (31) so next one will be moved to next month
When you create the Date object on 31th of October and then set the month to November (= 10!), which does not have 31 days, it will switch to the 1st of next month (December 1st).
It's dependent on current date. You initialize the date to "now" (new Date()), and today is Oct 31st.
If the day on your Date object is 31st and you call setMonth(), extra days will get carried on to the next month for months shorter than 31 days. If you try to setMonth(1) it will mean Feb 31st, so you get Mar 3rd.
To avoid the problem you can pass second argument the setMonth, which is the day to be set, e.g. dd.setMonth(10,30) (Nov 30).
Related
I need to create few records on Mondays using an api.
And the rule to get the Monday is that it should be either first Monday of a given month or last Monday of the given month.
For example:
If the input date range is 1 Sep 2020 - 30 Sep 2020, I need to pull 28 Sep 2020.
If the input date range is 1 Oct 2020 - 31 Oct 2020, I need to pull 26 Oct 2020.
If the input date range is 1 Nov 2020 - 30 Nov 2020, I need to pull 30 Nov 2020.
If the input date range is 1 Nov 2020 - 31 Dec 2020, I need to pull 28 Dec 2020.
What I did so far is I pulled all the Mondays of given month and stored them in an array. I tried pulling 1st or last Monday of the month, but this works for few months and not for few others.
Hence, I was thinking if I get to know the week of a given day(Monday), which overlaps 2 months, then I can pull that Monday.
So my question is how to get Monday of the week which overlaps 2 months? I am using moment js.
Maybe too late, but it could be helpful for future viewers.
The function takes start and end, but we only use end, so you can get rid of start as all the operations will be on end date in order to get the last monday. To achieve our goal we need to do two simple steps:
Get the end of the month with the end date.
Get the monday of the previous "calculated" date.
For the first step, we use End of Time in order to get the end of the month (the last day).
Mutates the original moment by setting it to the end of a unit of time.
Then we can get the Monday of the week the date is, and we can use Date of Week with the date of previous step.
Gets or sets the day of the week. [...] As of 2.1.0, a day name is also supported. This is parsed in the moment's current locale.
And taking your examples, we can test our function:
function lastMonday(start, end) {
console.log('Start is ', moment(start).format('LL'));
console.log('End is ', moment(end).format('LL'));
return moment(end).endOf('month').day('Monday');
}
console.log('Last monday is', lastMonday('2020-09-01', '2020-09-30').format('LL'));
console.log('Last monday is', lastMonday('2020-10-01', '2020-10-31').format('LL'));
console.log('Last monday is', lastMonday('2020-11-01', '2020-11-30').format('LL'));
console.log('Last monday is', lastMonday('2020-11-01', '2020-12-31').format('LL'));
<script src="https://momentjs.com/downloads/moment.js"></script>
This question already has answers here:
JavaScript function to add X months to a date
(24 answers)
Closed 2 years ago.
Code here:
const d = new Date(2020, 9, 31);
d.setMonth(8);
console.log(d);
// Result: Thursday October 1st (pardon can't type the whole thing, but you get what my problem is).
I expected September, pls help
According to mdn: The current day of month will have an impact on the behaviour of this method. Conceptually it will add the number of days given by the current day of the month to the 1st day of the new month specified as the parameter, to return the new date. For example, if the current value is 31st August 2016, calling setMonth with a value of 1 will return 2nd March 2016. This is because in 2016 February had 29 days.
So since your date has '31st' as day, after setting the month to September, it calculates '31' days hence you get the same month.
If I have a date of May 31, 2014, then if I say date.setMonth(date.getMonth() + 1) to get to the next month, I get July 01, 2014. I would expect to get June 30, 2014. I guess it's because June doesn't have 31 days so JavaScript does it best to avoid errors.
I wrote a special function to actually do the setDate, setMonth and setYear functions on that date object based on calculations. Seems like the setMonth alone doesnt do the right thing.
Ideas,
David
Are you trying to get 1 month from now? If so, what you are getting is correct. 1 Month from May 31 is July 1, not June 30. If you want it to only move to the second month only depending on the number of days in this month:
Ex: Jan 31st 2014 -> Feb 28th 2014
or the case you mentioned, you can use a small hack to use the min of the current days and the number of days in the next month to keep you in that same month:
// Assume its yesterday
var date = new Date(2014, 4, 31);
// Get the current date
var currentDate = date.getDate();
// Set to day 1 to avoid forward
date.setDate(1);
// Increase month by 1
date.setMonth(date.getMonth() + 1);
// Get max # of days in this new month
var daysInMonth = new Date(date.getYear(), date.getMonth()+1, 0).getDate();
// Set the date to the minimum of current date of days in month
date.setDate(Math.min(currentDate, daysInMonth));
I just had this same issue, I assumed JS Date handled the number of days for me when I changed the month number. I ended up using moment instead.
Reference:
Add months/days/etc: https://momentjs.com/docs/#/manipulating/add/
Substract months/days/etc: https://momentjs.com/docs/#/manipulating/subtract/
This code:
var dt = new Date('82/66/2005');
...gives a value for dt as Wed Nov 25 1992 00:00:00 GMT+0530 (IST) on Firefox.
How?
Fiddle - http://jsfiddle.net/4jyT3/1/
That date is not in a format that is specified to be supported by the Date constructor. I'm not surprised to find that most engines call it invalid, but apparently Firefox is attempting to make a date out of that. Even though it's not specified, most engines support month/day/year and all, last I checked, support year/month/day. Firefox appears to be applying year/month/day to the input, where most browsers see the invalid values and go with "invalid."
So Firefox is seeing 82 for year (and assuming 1982), 66 for month, and 2005 for day. JavaScript is usually very forgiving about out-of-bound values on dates, moving to the next month and such as necessary. And that's what's happening here: If you take January 1st 1982 and add a further 65 months and 2004 days, you end up on Nov 25 1992.
This code will reliably give you the date you mentioned:
var dt = new Date(1982, 65, 2005);
(65 instead of 66 because in the number form, months start with 0, but in string form, they start with 1.)
I can't re-produce this in Chrome, but I'll explain how FireFox arrives here.
new Date('82-66-2005');
Invalid date, let's guess what you wanted based on what we know about dates.
hyphen - format is usually yyyy-mm-dd
yy is short for 19yy
there are 12 months, so month 13 is Januaray of next year
similarly for days
So using this knowledge lets estimate it, assuming 365.25 days per year and 30.5 days per month.
// input
var year = 1982, // 19yy
bigMonth = 66,
bigDay = 2005;
// adjust day for years
var day = bigDay % 365.25;
year = year + (bigDay - day) / 365.25;
// adjust day for months
bigDay = day;
day = bigDay % 30.5;
bigMonth = bigMonth + (bigDay - day) / 30.5;
// adjust month for years
var month = bigMonth % 12;
year = year + (bigMonth - month) / 12;
console.log(year, month, day); // 1992 11 26.25
So it would be about the Nov 26th, 1992, which is pretty close to how your browser calculated it (it didn't need to estimate).
I have been using Stack Overflow for a number of months now, but this is my first post.
I require a function to convert a week number and and day of week into a dd/mm/yyyy format.
The date values i have to work with are in the format day/weekNumber. So for example: 3/43 converts to Wednesday 24 October 20XX. The year value will be the current year.
The day value starts at 1 (Monday).
I have found lots of functions on the internet (such as this, this and this). Some work with ISO 8601 dates, which i do not think will work for me. And i have not yet found one that works for me.
Thanks in advance,
This solution does require an extra library to be added, but I think it is really worth it. It is a momentjs library for manipulating dates and time. It is actively maintained and has a great documentation. Once you get the values for day and weekNumber (in our case 3 and 43), you should do as follows:
function formatInput(day, weekNumber){
var currentDate = moment(new Date()); // initialize moment to a current date
currentDate.startOf('year'); // set to Jan 1 12:00:00.000 pm this year
currentDate.add('w',weekNumber - 1); // add number of weeks to the beginning of the year (-1 because we are now at the 1st week)
currentDate.day(day); // set the day to the specified day, Monday being 1, Sunday 7
alert(currentDate.format("dddd, MMMM Do YYYY")); // return the formatted date string
return currentDate.format("dddd, MMMM Do YYYY");
}
I think this library might be useful to you later on and there are plenty of possibilities regarding date and time manipulation, as well as formatting options. There is also a great documentation written for momentjs.
So assuming you have the values of 3 and 43 separately, you can just do some simple maths on the first day of the current year:
Get 1st January Current Year
Add (43 * 7 + 3)
Something like this maybe:
var currentDate = new Date();
var startOfYear = new Date(currentDate.getFullYear(), 0, 1);//note: months start at 0
var daysToAdd = (43 * 7) + 3;
//add days
startOfYear.setDate(startOfYear.getDate() + daysToAdd);
Here is an example
EDIT
On second thoughts, I think I was wrong with your requirements. It seems you require a specific day of the week. Check this out for a better solution.
The problem is that it all depends on your definition of a week. This year starts on a sunday, so does that mean that 02/01/2012 (the first monday of this year) is the start of the second week?
My latest example will first find the start of the specified week, and then find the next occurrence of the specified day
According to ISO when dealing with week dates, the week starts on Monday and the first week of the year is the one that contains the first Thursday of the year. So for 2012, the first week started on Monday, 2 January and the first week of 2013 will start on Monday, 31 December 2012.
So if 3/43 is the third day of the 43rd week (which is the ISO date 2012-W43-3), then it can be converted it to a date object using:
function customWeekDateToDate(s) {
var d, n;
var bits = s.split('/');
// Calculate Monday of first week of year this year
d = new Date();
d = new Date(d.getFullYear(),0,1); // 1 jan this year
n = d.getDay();
d.setDate(d.getDate() + (-1 * n +( n<5? 1 : 8)));
// Add days
d.setDate(d.getDate() + --bits[0] + --bits[1] * 7);
return d;
}
console.log(customWeekDateToDate('3/43')); // 01 2012-10-24
Note that this uses dates, otherwise daylight saving changeovers may result in the wrong date.