summaryrefslogtreecommitdiffstats
path: root/src/corelib/tools
diff options
context:
space:
mode:
authorJohn Layt <john@layt.net>2010-03-30 08:55:33 (GMT)
committerOlivier Goffart <ogoffart@trolltech.com>2010-03-30 08:56:24 (GMT)
commit568475d98d77c3ade027eb88e571ca8b84088002 (patch)
tree8f139c3b9b7722f572ba65b1281e6c020b59fd4c /src/corelib/tools
parentbc4fe607fe65dca24460d4f612c5815b4767e988 (diff)
downloadQt-568475d98d77c3ade027eb88e571ca8b84088002.zip
Qt-568475d98d77c3ade027eb88e571ca8b84088002.tar.gz
Qt-568475d98d77c3ade027eb88e571ca8b84088002.tar.bz2
Fix QDate::isLeapYear() for years < 1
The current formula for isLeapYear() assumes that years -4, -8, etc are leap years in the Julian Calendar. This is not the case, leap years in fact fall in -1, -5, -9, etc as there is no year 0 in the Julian Calendar (count back 4 years from 4AD to confirm). The julianDayFromDate() and getDateFromJulianDay() functions correctly calculate this, but isValid() uses isLeapYear() and so causes setDate() to incorrectly reject valid dates. Sample test code to round-trip a jd to ymd and back to jd: QDate testDate; QDate loopDate = QDate::fromJulianDay(1); while ( loopDate.toJulianDay() <= 5373484 ) { // <= 9999-12-31 testDate.setDate( loopDate.year(), loopDate.month(), loopDate.day() ); if ( !testDate.isValid() || loopDate != testDate ) { qDebug() << "Round Trip failed : " << loopDate.toJulianDay() << " = " << loopDate.year() << loopDate.month() << loopDate.day() << " = " << testDate.toJulianDay(); } loopDate.addDays(1); } Before the fix, 29 Feb 1 BC (year = -1) and all other BC leap days returned by year() month() day() would result in setDate() failing. After the fix the round trip works fine. Merge-request: 2282 Reviewed-by: Olivier Goffart <ogoffart@trolltech.com>
Diffstat (limited to 'src/corelib/tools')
-rw-r--r--src/corelib/tools/qdatetime.cpp5
1 files changed, 4 insertions, 1 deletions
diff --git a/src/corelib/tools/qdatetime.cpp b/src/corelib/tools/qdatetime.cpp
index 54a4205..3e34d62 100644
--- a/src/corelib/tools/qdatetime.cpp
+++ b/src/corelib/tools/qdatetime.cpp
@@ -1336,7 +1336,10 @@ bool QDate::isValid(int year, int month, int day)
bool QDate::isLeapYear(int y)
{
if (y < 1582) {
- return qAbs(y) % 4 == 0;
+ if ( y < 1) { // No year 0 in Julian calendar, so -1, -5, -9 etc are leap years
+ ++y;
+ }
+ return y % 4 == 0;
} else {
return (y % 4 == 0 && y % 100 != 0) || y % 400 == 0;
}