the Date.getMonth() method has bug?

I tested in chrome and firefox, and here is the problem. The Date object's getMonth() method has an Bug? When I set the location date on someDay, like "2013-1-31"

then, the js code is :

var d = new Date();
d.setMonth(8);
d.getMonth();

The result is "9", why?

I found when the month has 31 days, run the setMonth method and the getMonth method will return wrong value

why?

Answers:

Answer

Let's break this down:

var d = new Date(); // date is now 2013-01-31
d.setMonth(1);      // date is now 2013-02-31, which is 3 days past 2013-02-28
x = d.getMonth();   // what to do, what to do, 3 days past 2013-02-28 is in March
                    // so, expect x to be March, which is 2

This is only an issue when the day value of d is greater than the maximum number of days in the month passed to setMonth(). Otherwise, it works as you'd expect.

Answer

The getMonth() method returns the month (from 0 to 11) for the specified date, according to local time.

Note: January is 0, February is 1, and so on.

Answer

Months in JavaScript are represented from 0-11. Month 1 would be February which only has 28/29 days, so when you set the month to 1, it tries to auto-correct the date to March to make a date that makes sense (since Feb 31st, makes no sense). Try it out by using the toDateString function to see what I mean:

 var d = new Date('2013/01/31');
 d.setMonth(2);
 console.log(d.toDateString()); // outputs Match 3rd, 2013

A little weird perhaps, but not buggy.

Answer

The getMonth() method returns the month (from 0 to 11) for the specified date, according to local time, eg. January is 0, February is 1.

Answer

In javascript month is start from 0. Assume today is 02/04/2012, when you setMonth(1) it will try to set to feb. Since max day in feb is 28/29, it move to the next month (March, which is 2)

Answer

The setMonth here is not what you expect, and what happens in better libraries. If you set a date 31.x.yyyy to x+1, probably the next month (x+1) will not have 31 days. So 31.x+1.yyyy will be changed to 1.x+2.yyyy.

In such case, the month will be increased by 2 - the date completely changed.

I had this problem with changing February->March, thanks God that was only a test.

Answer

I just resolved this way:

Example

var d = new Date('2013/01/31');

m = d.getMonth();

month = m*100/100 + 1;

Var month contains the correct value.

Answer

Simplest solution to this is to add second argument to setMonth:

var d = new Date();
d.setMonth(8,1);
d.getMonth(); //outputs 8

http://www.w3schools.com/jsref/jsref_setmonth.asp

Date.setMonth(month,day)

day: Optional. An integer representing the day of month Expected values are 1-31, but other values are allowed:

0 will result in the last day of the previous month -1 will result in the day before the last day of the previous month If the month has 31 days:

32 will result in the first day of the next month If the month has 30 days:

32 will result in the second day of the next month

Answer

This has to do with the current local date, even if the date you're setting is in the past or future (assuming you are correctly using the month range 0-11). This is because when you initialize Date(), it is using the current date. When you modify the date by using setFullYear(), setMonth() or setDate(), the default "current" values are still present and can shift the date.

If your current day of the month (today) is the 31st of the month and you then set a date in the past using setMonth(), setDate() where the month has less than your current 31 days, then Date() will give you the wrong month, even if you specifically state it. This is because when you setMonth(), the current date value of 31, which doesn't exist in the month you set, pushes it into the next month. Then when you set the date, the month never changes back.

If you set the day of the month before the month - setDate(), setMonth(), this fixes the problem, but has another similar issue / bug. If your current month only has 30 days and the date you're trying to set has 31 days, it will set the date of the month as 1, not 31. This is resolved if you set the month before the day - setMonth(), setDate(), but then you're back to the first problem.

Solutions:

  1. Get the values and then set the day of the month and month at the same time (as reetah suggested) - setMonth(8,1)
  2. Set the year with optional values to initialize setFullYear(1972, 0, 1), then setMonth, setDate.
  3. Set the month, set the day, then verify the month equals what you set it to and set it again if not - setMonth(), setDate(), setMonth()

function formatDate(date) {
  var monthNames = [
    "January", "February", "March",
    "April", "May", "June", "July",
    "August", "September", "October",
    "November", "December"
  ];

  var day = date.getDate();
  var monthIndex = date.getMonth();
  var year = date.getFullYear();

  return day + ' ' + monthNames[monthIndex] + ' ' + year;
}

var date = new Date();
if (date.getDate() < 31) {
	$("#mydate").text("YOUR LOCAL DATE (on your computer) MUST BE SET TO THE 31st for this bug to show.");
} else {
  date.setFullYear(1972);
  date.setMonth(8); // (month-1)
  date.setDate(24);
  var breakdown = "<br>Day: " + date.getDate() + "<br>Month: " + date.getMonth() + "<br>Year: " + date.getFullYear();
  $("#mydate").html("Set as September (8)<br><br>" + formatDate(date) + breakdown);

  var date = new Date();
  date.setFullYear(1972);
  date.setMonth(8, 24); // (month-1)
  var breakdown = "<br>Day: " + date.getDate() + "<br>Month: " + date.getMonth() + "<br>Year: " + date.getFullYear();
  $("#mydate4").html("Set as September (8) but set day before month<br><br>" + formatDate(date) + breakdown);

  date.setFullYear(1972);
  date.setMonth(9); //October (month-1)
  date.setDate(24);
  var breakdown = "<br>Day: " + date.getDate() + "<br>Month: " + date.getMonth() + "<br>Year: " + date.getFullYear();
  $("#mydate2").html("Set as October (9)<br><br>" + formatDate(date) + breakdown);

  var date = new Date();
  date.setFullYear(1972);
  date.setMonth(7); //Aug (month-1)
  date.setDate(24);
  var breakdown = "<br>Day: " + date.getDate() + "<br>Month: " + date.getMonth() + "<br>Year: " + date.getFullYear();
  $("#mydate3").html("Set as August (7)<br><br>" + formatDate(date) + breakdown);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
September 1972 has only 30 days.  If your current local day is 31, the Date will return October 1972 when you specify September before you specify the day of the month.
<br><br><div id="mydate" style="color: red;">
</div>
<br><br>
<div id="mydate4">
</div><br><br>
<div id="mydate2">
</div>
<br><br>
<div id="mydate3">
</div>

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us Javascript

©2020 All rights reserved.