Closed
Bug 361214
Opened 18 years ago
Closed 18 years ago
Date.setMonth method does not work logically
Categories
(Core :: JavaScript Engine, defect)
Tracking
()
VERIFIED
INVALID
People
(Reporter: trevor_garrick, Unassigned)
Details
User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1) Gecko/20061010 Firefox/2.0
Build Identifier: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1) Gecko/20061010 Firefox/2.0
When using the Date.setMonth() method, the month incrementing isn't logical (though this may be a difference of opinion how the method should work). When incrementing from a 31 day month into a 30 or 28(29) day month, the month will increment into the next month plus a couple of days (i.e. Date.setMonth(1) when the date object is Jan. 31, 2007 will produce March 3, 2007)
Reproducible: Always
Steps to Reproduce:
1.var foo = new Date(2007, 0, 31);
2.foo.setMonth(foo.getMonth() + 1);
3.document.write(foo.toString());
Actual Results:
Sat Mar 03 2007 00:00:00 GMT-0700 (MST)
Expected Results:
Logically, the setMonth() should have returned Feb. 28, 2007
I did a work around using the following code:
var MonthDays = new Array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
var oMat = new Date(2007, 0, 31);
var PayDate = oMat.getDate();
for (var x = 0; x < 60; x++) {
if (oMat.getFullYear() % 4 == 0) {
MonthDays[1] = 29;
}
else {
MonthDays[1] = 28;
}
if (oMat.getMonth() + 1 != 12) {
if (MonthDays[oMat.getMonth()+1] < PayDate) {
var currMonth = MonthDays[oMat.getMonth() + 1];
oMat.setMonth(oMat.getMonth() + 1, currMonth);
}
else {
oMat.setMonth(oMat.getMonth() + 1, PayDate);
}
}
else {
oMat.setMonth(oMat.getMonth() + 1, PayDate);
}
}
Obviously there are still some problems with this:
1. Doesn't take into account century non-leap years (2100, 2200, etc.)
2. It is inefficient to set the MonthDays[1] every iteration.
Comment 1•18 years ago
|
||
I think it works correctly but you are trying to do something which it's not designed for... You're setting 31 Feb 2007 which is equivalent to 3 March 2007.
This page (scroll down to the javascript section):
http://classicasp.aspfaq.com/date-time-routines-manipulation/how-do-i-calculate-dates-such-as-the-first-day-of-the-month.html
has details of a number of useful date functions, notably:
var ldtm = new Date(thisYear, thisMonth + 1, 0);
rw("Last day of this month:", ldtm.toDateString());
which should probably form the basis of what you are attempting.
I would set this INVALID but I couldn't actually find an authoritative source for 31 Feb = 3 Mar so I'll leave it to someone more qualified.
Comment 2•18 years ago
|
||
IE6, Firefox, Opera9 all agree on this. Invalid.
Status: UNCONFIRMED → RESOLVED
Closed: 18 years ago
Resolution: --- → INVALID
Comment 3•18 years ago
|
||
Verified by evaluating |var d = new Date(2006, 0, 31); d.setMonth(1);| against the spec. Specifically, note that step 7 in MakeDay returns the beginning of February, and step 8 determines the day which is 31 days after the first day in February (i.e., date wraparound occurs).
While looking at this, however, I discovered, that if the argument to setMonth is out of range (i.e., not 0-11), the date object isn't invalidated; filed as bug 361325.
Status: RESOLVED → VERIFIED
You need to log in
before you can comment on or make changes to this bug.
Description
•