diff options
author | John Layt <jlayt@kde.org> | 2011-08-25 07:54:16 +0100 |
---|---|---|
committer | Qt by Nokia <qt-info@nokia.com> | 2012-02-05 00:26:07 +0100 |
commit | 8327fa7c11f6c84ccc66be4365ee282a76288788 (patch) | |
tree | 680f7ef682a3beddc90106769664934cacd402c2 /tests/auto | |
parent | 31b4c5aa05376c2270122679c97a5727dc743d92 (diff) |
QDateTime: Store Julian Day as qint64
Store the QDate Julian Day number as an qint64 instead of uint32 to
enable support for dates before 2 January 4713 BCE. This changes the
possible date range to be approx 2.5 Quadrillion BC to 2.5 Quadrillion
AD. A qint32 was not used as it only covers 5 million BCE to 5 million
CE which does include Geological or Astronomical time.
The effective supported date range is currently 4800 BCE to 1.4 million
CE due to restrictions in existing conversion formulas. The effective
range will be extended later with new formulas.
Change-Id: Ib4345369455b31d4edae8c933b7721e76414e914
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'tests/auto')
-rw-r--r-- | tests/auto/corelib/tools/qdate/tst_qdate.cpp | 279 | ||||
-rw-r--r-- | tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp | 12 |
2 files changed, 216 insertions, 75 deletions
diff --git a/tests/auto/corelib/tools/qdate/tst_qdate.cpp b/tests/auto/corelib/tools/qdate/tst_qdate.cpp index 72c35354bf..4ce2a51902 100644 --- a/tests/auto/corelib/tools/qdate/tst_qdate.cpp +++ b/tests/auto/corelib/tools/qdate/tst_qdate.cpp @@ -48,6 +48,8 @@ class tst_QDate : public QObject Q_OBJECT private slots: void toString(); + void isNull_data(); + void isNull(); void isValid_data(); void isValid(); void julianDay_data(); @@ -64,6 +66,7 @@ private slots: void weekNumber_invalid(); void weekNumber_data(); void weekNumber(); + void julianDaysLimits(); void addDays_data(); void addDays(); void addMonths_data(); @@ -101,66 +104,92 @@ private slots: Q_DECLARE_METATYPE(QDate) +void tst_QDate::isNull_data() +{ + QTest::addColumn<qint64>("jd"); + QTest::addColumn<bool>("null"); + + qint64 minJd = std::numeric_limits<qint64>::min() / 2; + qint64 maxJd = std::numeric_limits<qint64>::max() / 2; + + QTest::newRow("qint64 min") << std::numeric_limits<qint64>::min() << true; + QTest::newRow("minJd - 1") << minJd - 1 << true; + QTest::newRow("minJd") << minJd << false; + QTest::newRow("minJd + 1") << minJd + 1 << false; + QTest::newRow("maxJd - 1") << maxJd - 1 << false; + QTest::newRow("maxJd") << maxJd << false; + QTest::newRow("maxJd + 1") << maxJd + 1 << true; + QTest::newRow("qint64 max") << std::numeric_limits<qint64>::max() << true; +} + +void tst_QDate::isNull() +{ + QFETCH(qint64, jd); + + QDate d = QDate::fromJulianDay(jd); + QTEST(d.isNull(), "null"); +} + void tst_QDate::isValid_data() { + qint64 nullJd = std::numeric_limits<qint64>::min(); + QTest::addColumn<int>("year"); QTest::addColumn<int>("month"); QTest::addColumn<int>("day"); - QTest::addColumn<uint>("jd"); + QTest::addColumn<qint64>("jd"); QTest::addColumn<bool>("valid"); - QTest::newRow("0-0-0") << 0 << 0 << 0 << 0U << false; - QTest::newRow("month 0") << 2000 << 0 << 1 << 0U << false; - QTest::newRow("day 0") << 2000 << 1 << 0 << 0U << false; + QTest::newRow("0-0-0") << 0 << 0 << 0 << nullJd << false; + QTest::newRow("month 0") << 2000 << 0 << 1 << nullJd << false; + QTest::newRow("day 0") << 2000 << 1 << 0 << nullJd << false; - QTest::newRow("month 13") << 2000 << 13 << 1 << 0U << false; + QTest::newRow("month 13") << 2000 << 13 << 1 << nullJd << false; // test leap years - QTest::newRow("non-leap") << 2006 << 2 << 29 << 0U << false; - QTest::newRow("normal leap") << 2004 << 2 << 29 << 2453065U << true; - QTest::newRow("century leap") << 1900 << 2 << 29 << 0U << false; - QTest::newRow("century leap") << 2100 << 2 << 29 << 0U << false; - QTest::newRow("400-years leap") << 2000 << 2 << 29 << 2451604U << true; - QTest::newRow("400-years leap 2") << 2400 << 2 << 29 << 2597701U << true; - QTest::newRow("400-years leap 3") << 1600 << 2 << 29 << 2305507U << true; - QTest::newRow("year 0") << 0 << 2 << 27 << 0U << false; + QTest::newRow("non-leap") << 2006 << 2 << 29 << nullJd << false; + QTest::newRow("normal leap") << 2004 << 2 << 29 << qint64(2453065) << true; + QTest::newRow("century leap") << 1900 << 2 << 29 << nullJd << false; + QTest::newRow("century leap") << 2100 << 2 << 29 << nullJd << false; + QTest::newRow("400-years leap") << 2000 << 2 << 29 << qint64(2451604) << true; + QTest::newRow("400-years leap 2") << 2400 << 2 << 29 << qint64(2597701) << true; + QTest::newRow("400-years leap 3") << 1600 << 2 << 29 << qint64(2305507) << true; + QTest::newRow("year 0") << 0 << 2 << 27 << nullJd << false; // test the number of days in months: - QTest::newRow("jan") << 2000 << 1 << 31 << 2451575U << true; - QTest::newRow("feb") << 2000 << 2 << 29 << 2451604U << true; // same data as 400-years leap - QTest::newRow("mar") << 2000 << 3 << 31 << 2451635U << true; - QTest::newRow("apr") << 2000 << 4 << 30 << 2451665U << true; - QTest::newRow("may") << 2000 << 5 << 31 << 2451696U << true; - QTest::newRow("jun") << 2000 << 6 << 30 << 2451726U << true; - QTest::newRow("jul") << 2000 << 7 << 31 << 2451757U << true; - QTest::newRow("aug") << 2000 << 8 << 31 << 2451788U << true; - QTest::newRow("sep") << 2000 << 9 << 30 << 2451818U << true; - QTest::newRow("oct") << 2000 << 10 << 31 << 2451849U << true; - QTest::newRow("nov") << 2000 << 11 << 30 << 2451879U << true; - QTest::newRow("dec") << 2000 << 12 << 31 << 2451910U << true; + QTest::newRow("jan") << 2000 << 1 << 31 << qint64(2451575) << true; + QTest::newRow("feb") << 2000 << 2 << 29 << qint64(2451604) << true; // same data as 400-years leap + QTest::newRow("mar") << 2000 << 3 << 31 << qint64(2451635) << true; + QTest::newRow("apr") << 2000 << 4 << 30 << qint64(2451665) << true; + QTest::newRow("may") << 2000 << 5 << 31 << qint64(2451696) << true; + QTest::newRow("jun") << 2000 << 6 << 30 << qint64(2451726) << true; + QTest::newRow("jul") << 2000 << 7 << 31 << qint64(2451757) << true; + QTest::newRow("aug") << 2000 << 8 << 31 << qint64(2451788) << true; + QTest::newRow("sep") << 2000 << 9 << 30 << qint64(2451818) << true; + QTest::newRow("oct") << 2000 << 10 << 31 << qint64(2451849) << true; + QTest::newRow("nov") << 2000 << 11 << 30 << qint64(2451879) << true; + QTest::newRow("dec") << 2000 << 12 << 31 << qint64(2451910) << true; // and invalid dates: - QTest::newRow("ijan") << 2000 << 1 << 32 << 0U << false; - QTest::newRow("ifeb") << 2000 << 2 << 30 << 0U << false; - QTest::newRow("imar") << 2000 << 3 << 32 << 0U << false; - QTest::newRow("iapr") << 2000 << 4 << 31 << 0U << false; - QTest::newRow("imay") << 2000 << 5 << 32 << 0U << false; - QTest::newRow("ijun") << 2000 << 6 << 31 << 0U << false; - QTest::newRow("ijul") << 2000 << 7 << 32 << 0U << false; - QTest::newRow("iaug") << 2000 << 8 << 32 << 0U << false; - QTest::newRow("isep") << 2000 << 9 << 31 << 0U << false; - QTest::newRow("ioct") << 2000 << 10 << 32 << 0U << false; - QTest::newRow("inov") << 2000 << 11 << 31 << 0U << false; - QTest::newRow("idec") << 2000 << 12 << 32 << 0U << false; + QTest::newRow("ijan") << 2000 << 1 << 32 << nullJd << false; + QTest::newRow("ifeb") << 2000 << 2 << 30 << nullJd << false; + QTest::newRow("imar") << 2000 << 3 << 32 << nullJd << false; + QTest::newRow("iapr") << 2000 << 4 << 31 << nullJd << false; + QTest::newRow("imay") << 2000 << 5 << 32 << nullJd << false; + QTest::newRow("ijun") << 2000 << 6 << 31 << nullJd << false; + QTest::newRow("ijul") << 2000 << 7 << 32 << nullJd << false; + QTest::newRow("iaug") << 2000 << 8 << 32 << nullJd << false; + QTest::newRow("isep") << 2000 << 9 << 31 << nullJd << false; + QTest::newRow("ioct") << 2000 << 10 << 32 << nullJd << false; + QTest::newRow("inov") << 2000 << 11 << 31 << nullJd << false; + QTest::newRow("idec") << 2000 << 12 << 32 << nullJd << false; // the beginning of the Julian Day calendar: - QTest::newRow("jd negative1") << -4714 << 1 << 1 << 0U << false; - QTest::newRow("jd negative2") << -4713 << 1 << 1 << 0U << false; - QTest::newRow("jd negative3") << -4713 << 1 << 2 << 1U << true; - QTest::newRow("jd negative4") << -4713 << 1 << 3 << 2U << true; - QTest::newRow("jd 0") << -4713 << 1 << 1 << 0U << false; - QTest::newRow("jd 1") << -4713 << 1 << 2 << 1U << true; - QTest::newRow("imminent overflow") << 11754508 << 12 << 13 << 4294967295U << true; + QTest::newRow("jd earliest formula") << -4800 << 1 << 1 << qint64( -31776) << true; + QTest::newRow("jd -1") << -4714 << 12 << 31 << qint64( -1) << true; + QTest::newRow("jd 0") << -4713 << 1 << 1 << qint64( 0) << true; + QTest::newRow("jd 1") << -4713 << 1 << 2 << qint64( 1) << true; + QTest::newRow("jd latest formula") << 1400000 << 12 << 31 << qint64(513060925) << true; } void tst_QDate::isValid() @@ -168,7 +197,7 @@ void tst_QDate::isValid() QFETCH(int, year); QFETCH(int, month); QFETCH(int, day); - QFETCH(uint, jd); + QFETCH(qint64, jd); QFETCH(bool, valid); QCOMPARE(QDate::isValid(year, month, day), valid); @@ -176,6 +205,7 @@ void tst_QDate::isValid() QDate d; d.setDate(year, month, day); QCOMPARE(d.isValid(), valid); + QCOMPARE(d.toJulianDay(), jd); if (valid) { QCOMPARE(d.year(), year); @@ -198,15 +228,15 @@ void tst_QDate::julianDay() QFETCH(int, year); QFETCH(int, month); QFETCH(int, day); - QFETCH(uint, jd); + QFETCH(qint64, jd); { QDate d; d.setDate(year, month, day); - QCOMPARE(uint(d.toJulianDay()), jd); + QCOMPARE(d.toJulianDay(), jd); } - if (jd) { + if (jd != std::numeric_limits<qint64>::min()) { QDate d = QDate::fromJulianDay(jd); QCOMPARE(d.year(), year); QCOMPARE(d.month(), month); @@ -233,7 +263,15 @@ void tst_QDate::dayOfWeek_data() QTest::newRow("data9") << 1815 << 6 << 15 << 4; QTest::newRow("data10") << 1500 << 1 << 1 << 3; QTest::newRow("data11") << -1500 << 1 << 1 << 7; - QTest::newRow("data12") << -4713 << 1 << 2 << 2; + QTest::newRow("data12") << -4800 << 1 << 1 << 5; + QTest::newRow("data13") << -4800 << 1 << 4 << 1; + QTest::newRow("data14") << -4800 << 1 << 5 << 2; + QTest::newRow("data15") << -4800 << 1 << 6 << 3; + QTest::newRow("data16") << -4800 << 1 << 7 << 4; + QTest::newRow("data17") << -4800 << 1 << 8 << 5; + QTest::newRow("data18") << -4800 << 1 << 9 << 6; + QTest::newRow("data19") << -4800 << 1 << 10 << 7; + QTest::newRow("data20") << -4800 << 1 << 11 << 1; } void tst_QDate::dayOfWeek() @@ -266,8 +304,8 @@ void tst_QDate::dayOfYear_data() QTest::newRow("data9") << 1582 << 12 << 31 << 355; QTest::newRow("data10") << 1500 << 1 << 1 << 1; QTest::newRow("data11") << -1500 << 12 << 31 << 365; - QTest::newRow("data12") << -4713 << 1 << 2 << 2; - QTest::newRow("data13") << -4713 << 12 << 31 << 366; + QTest::newRow("data12") << -4800 << 1 << 1 << 1; + QTest::newRow("data13") << -4800 << 12 << 31 << 365; } void tst_QDate::dayOfYear() @@ -393,6 +431,68 @@ void tst_QDate::weekNumber_invalid() QCOMPARE( dt.weekNumber( &yearNumber ), 0 ); } +void tst_QDate::julianDaysLimits() +{ + qint64 min = std::numeric_limits<qint64>::min(); + qint64 max = std::numeric_limits<qint64>::max(); + qint64 minJd = std::numeric_limits<qint64>::min() / 2; + qint64 maxJd = std::numeric_limits<qint64>::max() / 2; + + QDate maxDate = QDate::fromJulianDay(maxJd); + QDate minDate = QDate::fromJulianDay(minJd); + QDate zeroDate = QDate::fromJulianDay(0); + + QDate dt = QDate::fromJulianDay(min); + QCOMPARE(dt.isValid(), false); + dt = QDate::fromJulianDay(minJd - 1); + QCOMPARE(dt.isValid(), false); + dt = QDate::fromJulianDay(minJd); + QCOMPARE(dt.isValid(), true); + dt = QDate::fromJulianDay(minJd + 1); + QCOMPARE(dt.isValid(), true); + dt = QDate::fromJulianDay(maxJd - 1); + QCOMPARE(dt.isValid(), true); + dt = QDate::fromJulianDay(maxJd); + QCOMPARE(dt.isValid(), true); + dt = QDate::fromJulianDay(maxJd + 1); + QCOMPARE(dt.isValid(), false); + dt = QDate::fromJulianDay(max); + QCOMPARE(dt.isValid(), false); + + dt = maxDate.addDays(1); + QCOMPARE(dt.isValid(), false); + dt = maxDate.addDays(0); + QCOMPARE(dt.isValid(), true); + dt = maxDate.addDays(-1); + QCOMPARE(dt.isValid(), true); + dt = maxDate.addDays(max); + QCOMPARE(dt.isValid(), false); + dt = maxDate.addDays(min); + QCOMPARE(dt.isValid(), false); + + dt = minDate.addDays(-1); + QCOMPARE(dt.isValid(), false); + dt = minDate.addDays(0); + QCOMPARE(dt.isValid(), true); + dt = minDate.addDays(1); + QCOMPARE(dt.isValid(), true); + dt = minDate.addDays(min); + QCOMPARE(dt.isValid(), false); + dt = minDate.addDays(max); + QCOMPARE(dt.isValid(), true); + + dt = zeroDate.addDays(-1); + QCOMPARE(dt.isValid(), true); + dt = zeroDate.addDays(0); + QCOMPARE(dt.isValid(), true); + dt = zeroDate.addDays(1); + QCOMPARE(dt.isValid(), true); + dt = zeroDate.addDays(min); + QCOMPARE(dt.isValid(), false); + dt = zeroDate.addDays(max); + QCOMPARE(dt.isValid(), false); +} + void tst_QDate::addDays() { QFETCH( int, year ); @@ -435,9 +535,8 @@ void tst_QDate::addDays_data() QTest::newRow( "data10" ) << 2000 << 2 << 28 << -1 << 2000 << 2 << 27; QTest::newRow( "data11" ) << 2001 << 2 << 28 << -30 << 2001 << 1 << 29; - QDate invalid; - QTest::newRow( "data12" ) << -4713 << 1 << 2 << -2 - << invalid.year() << invalid.month() << invalid.day(); + QTest::newRow( "data12" ) << -4713 << 1 << 2 << -2 << -4714 << 12 << 31; + QTest::newRow( "data13" ) << -4713 << 1 << 2 << 2 << -4713 << 1 << 4; } void tst_QDate::addMonths() @@ -553,15 +652,31 @@ void tst_QDate::addYears_data() void tst_QDate::daysTo() { + qint64 minJd = std::numeric_limits<qint64>::min() / 2; + qint64 maxJd = std::numeric_limits<qint64>::max() / 2; + QDate dt1(2000, 1, 1); QDate dt2(2000, 1, 5); - QCOMPARE(dt1.daysTo(dt2), 4); - QCOMPARE(dt2.daysTo(dt1), -4); + QCOMPARE(dt1.daysTo(dt2), (qint64) 4); + QCOMPARE(dt2.daysTo(dt1), (qint64) -4); + dt1.setDate(0, 0, 0); - QCOMPARE(dt1.daysTo(dt2), 0); + QCOMPARE(dt1.daysTo(dt2), (qint64) 0); dt1.setDate(2000, 1, 1); dt2.setDate(0, 0, 0); - QCOMPARE(dt1.daysTo(dt2), 0); + QCOMPARE(dt1.daysTo(dt2), (qint64) 0); + + + QDate maxDate = QDate::fromJulianDay(maxJd); + QDate minDate = QDate::fromJulianDay(minJd); + QDate zeroDate = QDate::fromJulianDay(0); + + QCOMPARE(maxDate.daysTo(minDate), minJd - maxJd); + QCOMPARE(minDate.daysTo(maxDate), maxJd - minJd); + QCOMPARE(maxDate.daysTo(zeroDate), -maxJd); + QCOMPARE(zeroDate.daysTo(maxDate), maxJd); + QCOMPARE(minDate.daysTo(zeroDate), -minJd); + QCOMPARE(zeroDate.daysTo(minDate), minJd); } void tst_QDate::operator_eq_eq() @@ -798,6 +913,8 @@ void tst_QDate::toString_format() void tst_QDate::isLeapYear() { + QVERIFY(QDate::isLeapYear(-4801)); + QVERIFY(!QDate::isLeapYear(-4800)); QVERIFY(QDate::isLeapYear(-4445)); QVERIFY(!QDate::isLeapYear(-4444)); QVERIFY(!QDate::isLeapYear(-6)); @@ -1065,28 +1182,52 @@ void tst_QDate::roundtrip() const // year(), month(), day(), julianDayFromDate(), and getDateFromJulianDay() // to ensure they are internally consistent (but doesn't guarantee correct) - // Test Julian round trip in both BC and AD + // Test Julian round trip around JD 0 and current low end of valid range QDate testDate; - QDate loopDate = QDate::fromJulianDay(1684899); // 1 Jan 100 BC - while ( loopDate.toJulianDay() <= 1757948 ) { // 31 Dec 100 AD - testDate.setDate( loopDate.year(), loopDate.month(), loopDate.day() ); - QCOMPARE( loopDate.toJulianDay(), testDate.toJulianDay() ); + QDate loopDate = QDate::fromJulianDay(-31776); // 1 Jan 4800 BC + while (loopDate.toJulianDay() <= 5113) { // 31 Dec 4700 AD + testDate.setDate(loopDate.year(), loopDate.month(), loopDate.day()); + QCOMPARE(loopDate.toJulianDay(), testDate.toJulianDay()); + loopDate = loopDate.addDays(1); + } + + // Test Julian round trip in both BC and AD + loopDate = QDate::fromJulianDay(1684899); // 1 Jan 100 BC + while (loopDate.toJulianDay() <= 1757948) { // 31 Dec 100 AD + testDate.setDate(loopDate.year(), loopDate.month(), loopDate.day()); + QCOMPARE(loopDate.toJulianDay(), testDate.toJulianDay()); loopDate = loopDate.addDays(1); } // Test Julian and Gregorian round trip during changeover period loopDate = QDate::fromJulianDay(2298153); // 1 Jan 1580 AD - while ( loopDate.toJulianDay() <= 2300334 ) { // 31 Dec 1585 AD - testDate.setDate( loopDate.year(), loopDate.month(), loopDate.day() ); - QCOMPARE( loopDate.toJulianDay(), testDate.toJulianDay() ); + while (loopDate.toJulianDay() <= 2300334) { // 31 Dec 1585 AD + testDate.setDate(loopDate.year(), loopDate.month(), loopDate.day()); + QCOMPARE(loopDate.toJulianDay(), testDate.toJulianDay()); loopDate = loopDate.addDays(1); } // Test Gregorian round trip during current useful period loopDate = QDate::fromJulianDay(2378497); // 1 Jan 1900 AD - while ( loopDate.toJulianDay() <= 2488433 ) { // 31 Dec 2100 AD - testDate.setDate( loopDate.year(), loopDate.month(), loopDate.day() ); - QCOMPARE( loopDate.toJulianDay(), testDate.toJulianDay() ); + while (loopDate.toJulianDay() <= 2488433) { // 31 Dec 2100 AD + testDate.setDate(loopDate.year(), loopDate.month(), loopDate.day()); + QCOMPARE(loopDate.toJulianDay(), testDate.toJulianDay()); + loopDate = loopDate.addDays(1); + } + + // Test Gregorian round trip at top end of widget/format range + loopDate = QDate::fromJulianDay(5336961); // 1 Jan 9900 AD + while (loopDate.toJulianDay() <= 5373484) { // 31 Dec 9999 AD + testDate.setDate(loopDate.year(), loopDate.month(), loopDate.day()); + QCOMPARE(loopDate.toJulianDay(), testDate.toJulianDay()); + loopDate = loopDate.addDays(1); + } + + // Test Gregorian round trip at top end of conversion range + loopDate = QDate::fromJulianDay(513024036); // 1 Jan 1399900 AD + while (loopDate.toJulianDay() <= 513060925) { // 31 Dec 1400000 AD + testDate.setDate(loopDate.year(), loopDate.month(), loopDate.day()); + QCOMPARE(loopDate.toJulianDay(), testDate.toJulianDay()); loopDate = loopDate.addDays(1); } } diff --git a/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp b/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp index 2cbac82d3b..2cb3db533e 100644 --- a/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp +++ b/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp @@ -883,22 +883,22 @@ void tst_QDateTime::daysTo() QDateTime dt2(QDate(1760, 2, 2), QTime()); QDateTime dt3(QDate(1760, 3, 2), QTime()); - QCOMPARE(dt1.daysTo(dt2), 31); + QCOMPARE(dt1.daysTo(dt2), (qint64) 31); QCOMPARE(dt1.addDays(31), dt2); - QCOMPARE(dt2.daysTo(dt3), 29); + QCOMPARE(dt2.daysTo(dt3), (qint64) 29); QCOMPARE(dt2.addDays(29), dt3); - QCOMPARE(dt1.daysTo(dt3), 60); + QCOMPARE(dt1.daysTo(dt3), (qint64) 60); QCOMPARE(dt1.addDays(60), dt3); - QCOMPARE(dt2.daysTo(dt1), -31); + QCOMPARE(dt2.daysTo(dt1), (qint64) -31); QCOMPARE(dt2.addDays(-31), dt1); - QCOMPARE(dt3.daysTo(dt2), -29); + QCOMPARE(dt3.daysTo(dt2), (qint64) -29); QCOMPARE(dt3.addDays(-29), dt2); - QCOMPARE(dt3.daysTo(dt1), -60); + QCOMPARE(dt3.daysTo(dt1), (qint64) -60); QCOMPARE(dt3.addDays(-60), dt1); } |