1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
10 #include <cppunit/TestFixture.h>
11 #include <cppunit/extensions/HelperMacros.h>
13 #include <tools/date.hxx>
17 class DateTest
: public CppUnit::TestFixture
22 void testGetDaysInYear();
23 void testValidGregorianDate();
26 void testGetDayOfWeek();
27 void testGetDaysInMonth();
29 void testIsEndOfMonth();
31 CPPUNIT_TEST_SUITE(DateTest
);
32 CPPUNIT_TEST(testDate
);
33 CPPUNIT_TEST(testLeapYear
);
34 CPPUNIT_TEST(testGetDaysInYear
);
35 CPPUNIT_TEST(testValidGregorianDate
);
36 CPPUNIT_TEST(testValidDate
);
37 CPPUNIT_TEST(testNormalize
);
38 CPPUNIT_TEST(testGetDayOfWeek
);
39 CPPUNIT_TEST(testGetDaysInMonth
);
40 CPPUNIT_TEST(testIsBetween
);
41 CPPUNIT_TEST(testIsEndOfMonth
);
42 CPPUNIT_TEST_SUITE_END();
45 void DateTest::testDate()
47 const Date
aCE(1, 1, 1); // first day CE
48 const Date
aBCE(31, 12, -1); // last day BCE
49 const Date
aMin(1, 1, -32768); // minimum date
50 const Date
aMax(31, 12, 32767); // maximum date
51 Date
aDate(Date::EMPTY
);
52 const sal_Int32 kMinDays
= -11968265;
53 const sal_Int32 kMaxDays
= 11967900;
55 // Last day BCE to first day CE is 1 day difference.
56 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32
>(1), aCE
- aBCE
);
57 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32
>(-1), aBCE
- aCE
);
60 CPPUNIT_ASSERT_EQUAL(aCE
.GetDate(), aDate
.GetDate());
63 CPPUNIT_ASSERT_EQUAL(aBCE
.GetDate(), aDate
.GetDate());
65 // The entire BCE and CE ranges cover that many days. Day 0 is -0001-12-31
66 CPPUNIT_ASSERT_EQUAL(kMaxDays
, aMax
- aBCE
);
67 CPPUNIT_ASSERT_EQUAL(kMinDays
, aMin
- aBCE
);
69 // Truncate at limits, not under-/overflow or wrap.
72 CPPUNIT_ASSERT_EQUAL(aMin
.GetDate(), aDate
.GetDate());
75 CPPUNIT_ASSERT_EQUAL(aMax
.GetDate(), aDate
.GetDate());
77 aDate
.AddDays(kMinDays
- 10);
78 CPPUNIT_ASSERT_EQUAL(aMin
.GetDate(), aDate
.GetDate());
80 aDate
.AddDays(kMaxDays
+ 10);
81 CPPUNIT_ASSERT_EQUAL(aMax
.GetDate(), aDate
.GetDate());
85 CPPUNIT_ASSERT_EQUAL(aMax
.GetDate(), aDate
.GetDate());
86 CPPUNIT_ASSERT(!aDate
.IsEmpty());
88 // 0001-00-x normalized to -0001-12-x
93 CPPUNIT_ASSERT_EQUAL(Date(22, 12, -1).GetDate(), aDate
.GetDate());
95 sal_uInt32 nExpected
= 11222;
96 CPPUNIT_ASSERT_EQUAL(nExpected
, aDate
.GetDateUnsigned());
97 // 1999-02-32 normalized to 1999-03-04
102 CPPUNIT_ASSERT_EQUAL(Date(4, 3, 1999).GetDate(), aDate
.GetDate());
104 // Empty date is not normalized and stays empty date.
105 aDate
= Date(Date::EMPTY
);
107 CPPUNIT_ASSERT_EQUAL(Date(Date::EMPTY
).GetDate(), aDate
.GetDate());
108 CPPUNIT_ASSERT(!aDate
.IsValidDate()); // GetDate() also shall have no normalizing side effect
110 // 0000-01-00 normalized to -0001-12-31
111 // SetYear(0) asserts, use empty date to force.
112 aDate
= Date(Date::EMPTY
);
116 CPPUNIT_ASSERT_EQUAL(Date(31, 12, -1).GetDate(), aDate
.GetDate());
118 // 1999-00-00 normalized to 1998-12-31 (not 1998-11-30, or otherwise
119 // also 0001-00-00 should be -0001-11-30 which it should not, should it?)
124 CPPUNIT_ASSERT_EQUAL(Date(31, 12, 1998).GetDate(), aDate
.GetDate());
126 // 0001-00-00 normalized to -0001-12-31
131 CPPUNIT_ASSERT_EQUAL(Date(31, 12, -1).GetDate(), aDate
.GetDate());
134 void DateTest::testLeapYear()
137 Date
aDate(1, 1, 2000);
138 CPPUNIT_ASSERT(aDate
.IsLeapYear());
142 Date
aDate(1, 1, 1900);
143 CPPUNIT_ASSERT(!aDate
.IsLeapYear());
147 Date
aDate(1, 1, 1999);
148 CPPUNIT_ASSERT(!aDate
.IsLeapYear());
152 Date
aDate(1, 1, 2004);
153 CPPUNIT_ASSERT(aDate
.IsLeapYear());
157 Date
aDate(1, 1, 400);
158 CPPUNIT_ASSERT(aDate
.IsLeapYear());
162 // Year -1 is a leap year.
163 Date
aDate(28, 2, -1);
165 CPPUNIT_ASSERT(aDate
.IsLeapYear());
166 CPPUNIT_ASSERT_EQUAL(Date(29, 2, -1).GetDate(), aDate
.GetDate());
170 Date
aDate(1, 3, -1);
172 CPPUNIT_ASSERT(aDate
.IsLeapYear());
173 CPPUNIT_ASSERT_EQUAL(Date(29, 2, -1).GetDate(), aDate
.GetDate());
177 // Year -5 is a leap year.
178 Date
aDate(28, 2, -5);
180 CPPUNIT_ASSERT(aDate
.IsLeapYear());
181 CPPUNIT_ASSERT_EQUAL(Date(29, 2, -5).GetDate(), aDate
.GetDate());
185 Date
aDate(1, 3, -5);
187 CPPUNIT_ASSERT(aDate
.IsLeapYear());
188 CPPUNIT_ASSERT_EQUAL(Date(29, 2, -5).GetDate(), aDate
.GetDate());
192 void DateTest::testGetDaysInYear()
195 Date
aDate(1, 1, 2000);
196 CPPUNIT_ASSERT_EQUAL(sal_uInt16(366), aDate
.GetDaysInYear());
200 Date
aDate(1, 1, 1900);
201 CPPUNIT_ASSERT_EQUAL(sal_uInt16(365), aDate
.GetDaysInYear());
205 Date
aDate(1, 1, 1999);
206 CPPUNIT_ASSERT_EQUAL(sal_uInt16(365), aDate
.GetDaysInYear());
210 Date
aDate(1, 1, 2004);
211 CPPUNIT_ASSERT_EQUAL(sal_uInt16(366), aDate
.GetDaysInYear());
215 Date
aDate(1, 1, 400);
216 CPPUNIT_ASSERT_EQUAL(sal_uInt16(366), aDate
.GetDaysInYear());
220 void DateTest::testValidGregorianDate()
223 Date
aDate(1, 0, 2000);
224 CPPUNIT_ASSERT(!aDate
.IsValidAndGregorian());
228 Date
aDate(1, 13, 2000);
229 CPPUNIT_ASSERT(!aDate
.IsValidAndGregorian());
233 Date
aDate(1, 1, 1581);
234 CPPUNIT_ASSERT(!aDate
.IsValidAndGregorian());
238 Date
aDate(1, 9, 1582);
239 CPPUNIT_ASSERT(!aDate
.IsValidAndGregorian());
243 Date
aDate(1, 10, 1582);
244 CPPUNIT_ASSERT(!aDate
.IsValidAndGregorian());
248 Date
aDate(32, 1, 2000);
249 CPPUNIT_ASSERT(!aDate
.IsValidAndGregorian());
253 Date
aDate(29, 2, 2000);
254 CPPUNIT_ASSERT(aDate
.IsValidAndGregorian());
258 Date
aDate(29, 2, 2001);
259 CPPUNIT_ASSERT(!aDate
.IsValidAndGregorian());
263 Date
aDate(32, 3, 2000);
264 CPPUNIT_ASSERT(!aDate
.IsValidAndGregorian());
268 Date
aDate(31, 4, 2000);
269 CPPUNIT_ASSERT(!aDate
.IsValidAndGregorian());
273 Date
aDate(32, 5, 2000);
274 CPPUNIT_ASSERT(!aDate
.IsValidAndGregorian());
278 Date
aDate(31, 6, 2000);
279 CPPUNIT_ASSERT(!aDate
.IsValidAndGregorian());
283 Date
aDate(32, 7, 2000);
284 CPPUNIT_ASSERT(!aDate
.IsValidAndGregorian());
288 Date
aDate(32, 8, 2000);
289 CPPUNIT_ASSERT(!aDate
.IsValidAndGregorian());
293 Date
aDate(31, 9, 2000);
294 CPPUNIT_ASSERT(!aDate
.IsValidAndGregorian());
298 Date
aDate(32, 10, 2000);
299 CPPUNIT_ASSERT(!aDate
.IsValidAndGregorian());
303 Date
aDate(31, 11, 2000);
304 CPPUNIT_ASSERT(!aDate
.IsValidAndGregorian());
308 Date
aDate(32, 12, 2000);
309 CPPUNIT_ASSERT(!aDate
.IsValidAndGregorian());
313 void DateTest::testValidDate()
316 // Empty date is not a valid date.
317 Date
aDate(Date::EMPTY
);
318 CPPUNIT_ASSERT(aDate
.IsEmpty());
319 CPPUNIT_ASSERT(!aDate
.IsValidDate());
323 Date
aDate(32, 1, 2000);
324 CPPUNIT_ASSERT(!aDate
.IsValidDate());
328 Date
aDate(29, 2, 2000);
329 CPPUNIT_ASSERT(aDate
.IsValidDate());
333 Date
aDate(29, 2, 2001);
334 CPPUNIT_ASSERT(!aDate
.IsValidDate());
338 Date
aDate(32, 3, 2000);
339 CPPUNIT_ASSERT(!aDate
.IsValidDate());
343 Date
aDate(31, 4, 2000);
344 CPPUNIT_ASSERT(!aDate
.IsValidDate());
348 Date
aDate(32, 5, 2000);
349 CPPUNIT_ASSERT(!aDate
.IsValidDate());
353 Date
aDate(31, 6, 2000);
354 CPPUNIT_ASSERT(!aDate
.IsValidDate());
358 Date
aDate(32, 7, 2000);
359 CPPUNIT_ASSERT(!aDate
.IsValidDate());
363 Date
aDate(32, 8, 2000);
364 CPPUNIT_ASSERT(!aDate
.IsValidDate());
368 Date
aDate(31, 9, 2000);
369 CPPUNIT_ASSERT(!aDate
.IsValidDate());
373 Date
aDate(32, 10, 2000);
374 CPPUNIT_ASSERT(!aDate
.IsValidDate());
378 Date
aDate(31, 11, 2000);
379 CPPUNIT_ASSERT(!aDate
.IsValidDate());
383 Date
aDate(32, 12, 2000);
384 CPPUNIT_ASSERT(!aDate
.IsValidDate());
388 void DateTest::testNormalize()
391 Date
aDate(32, 2, 1999);
393 Date
aExpectedDate(4, 3, 1999);
394 CPPUNIT_ASSERT_EQUAL(aExpectedDate
, aDate
);
398 Date
aDate(1, 13, 1999);
400 Date
aExpectedDate(1, 1, 2000);
401 CPPUNIT_ASSERT_EQUAL(aExpectedDate
, aDate
);
405 Date
aDate(42, 13, 1999);
407 Date
aExpectedDate(11, 2, 2000);
408 CPPUNIT_ASSERT_EQUAL(aExpectedDate
, aDate
);
414 Date
aExpectedDate(1, 12, -1);
415 CPPUNIT_ASSERT_EQUAL(aExpectedDate
, aDate
);
419 void DateTest::testGetDayOfWeek()
422 DayOfWeek eExpectedDay
= DayOfWeek::MONDAY
;
423 Date
aDate(30, 4, 2018);
424 CPPUNIT_ASSERT_EQUAL(eExpectedDay
, aDate
.GetDayOfWeek());
428 DayOfWeek eExpectedDay
= DayOfWeek::TUESDAY
;
429 Date
aDate(1, 5, 2018);
430 CPPUNIT_ASSERT_EQUAL(eExpectedDay
, aDate
.GetDayOfWeek());
434 DayOfWeek eExpectedDay
= DayOfWeek::WEDNESDAY
;
435 Date
aDate(2, 5, 2018);
436 CPPUNIT_ASSERT_EQUAL(eExpectedDay
, aDate
.GetDayOfWeek());
440 DayOfWeek eExpectedDay
= DayOfWeek::THURSDAY
;
441 Date
aDate(3, 5, 2018);
442 CPPUNIT_ASSERT_EQUAL(eExpectedDay
, aDate
.GetDayOfWeek());
446 DayOfWeek eExpectedDay
= DayOfWeek::FRIDAY
;
447 Date
aDate(4, 5, 2018);
448 CPPUNIT_ASSERT_EQUAL(eExpectedDay
, aDate
.GetDayOfWeek());
452 DayOfWeek eExpectedDay
= DayOfWeek::SATURDAY
;
453 Date
aDate(5, 5, 2018);
454 CPPUNIT_ASSERT_EQUAL(eExpectedDay
, aDate
.GetDayOfWeek());
458 DayOfWeek eExpectedDay
= DayOfWeek::SUNDAY
;
459 Date
aDate(6, 5, 2018);
460 CPPUNIT_ASSERT_EQUAL(eExpectedDay
, aDate
.GetDayOfWeek());
464 void DateTest::testGetDaysInMonth()
467 Date
aDate(1, 1, 2000);
468 CPPUNIT_ASSERT_EQUAL(sal_uInt16(31), aDate
.GetDaysInMonth());
472 Date
aDate(1, 2, 2000);
473 CPPUNIT_ASSERT_EQUAL(sal_uInt16(29), aDate
.GetDaysInMonth());
477 Date
aDate(1, 2, 1999);
478 CPPUNIT_ASSERT_EQUAL(sal_uInt16(28), aDate
.GetDaysInMonth());
482 Date
aDate(1, 3, 2000);
483 CPPUNIT_ASSERT_EQUAL(sal_uInt16(31), aDate
.GetDaysInMonth());
487 Date
aDate(1, 4, 2000);
488 CPPUNIT_ASSERT_EQUAL(sal_uInt16(30), aDate
.GetDaysInMonth());
492 Date
aDate(1, 5, 2000);
493 CPPUNIT_ASSERT_EQUAL(sal_uInt16(31), aDate
.GetDaysInMonth());
497 Date
aDate(1, 6, 2000);
498 CPPUNIT_ASSERT_EQUAL(sal_uInt16(30), aDate
.GetDaysInMonth());
502 Date
aDate(1, 7, 2000);
503 CPPUNIT_ASSERT_EQUAL(sal_uInt16(31), aDate
.GetDaysInMonth());
507 Date
aDate(1, 8, 2000);
508 CPPUNIT_ASSERT_EQUAL(sal_uInt16(31), aDate
.GetDaysInMonth());
512 Date
aDate(1, 9, 2000);
513 CPPUNIT_ASSERT_EQUAL(sal_uInt16(30), aDate
.GetDaysInMonth());
517 Date
aDate(1, 10, 2000);
518 CPPUNIT_ASSERT_EQUAL(sal_uInt16(31), aDate
.GetDaysInMonth());
522 Date
aDate(1, 11, 2000);
523 CPPUNIT_ASSERT_EQUAL(sal_uInt16(30), aDate
.GetDaysInMonth());
527 Date
aDate(1, 12, 2000);
528 CPPUNIT_ASSERT_EQUAL(sal_uInt16(31), aDate
.GetDaysInMonth());
532 void DateTest::testIsBetween()
534 Date
aDate(6, 4, 2018);
535 CPPUNIT_ASSERT(aDate
.IsBetween(Date(1, 1, 2018), Date(1, 12, 2018)));
538 void DateTest::testIsEndOfMonth()
541 Date
aDate(31, 12, 2000);
542 CPPUNIT_ASSERT(aDate
.IsEndOfMonth());
546 Date
aDate(30, 12, 2000);
547 CPPUNIT_ASSERT(!aDate
.IsEndOfMonth());
551 Date
aDate(29, 2, 2000);
552 CPPUNIT_ASSERT(aDate
.IsEndOfMonth());
556 Date
aDate(28, 2, 2000);
557 CPPUNIT_ASSERT(!aDate
.IsEndOfMonth());
561 CPPUNIT_TEST_SUITE_REGISTRATION(DateTest
);
564 /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */