1//
2// DateTimeTest.cpp
3//
4// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
5// and Contributors.
6//
7// SPDX-License-Identifier: BSL-1.0
8//
9
10
11#include "DateTimeTest.h"
12#include "Poco/CppUnit/TestCaller.h"
13#include "Poco/CppUnit/TestSuite.h"
14#include "Poco/DateTime.h"
15#include "Poco/Timestamp.h"
16#include "Poco/Timespan.h"
17#include "Poco/Exception.h"
18
19
20using Poco::Timestamp;
21using Poco::DateTime;
22using Poco::Timespan;
23using Poco::AssertionViolationException;
24
25
26DateTimeTest::DateTimeTest(const std::string& rName): CppUnit::TestCase(rName)
27{
28}
29
30
31DateTimeTest::~DateTimeTest()
32{
33}
34
35
36void DateTimeTest::testTimestamp()
37{
38 Timestamp ts(0); // Unix epoch 1970-01-01 00:00:00 Thursday
39 DateTime dt(ts);
40 assertTrue (dt.year() == 1970);
41 assertTrue (dt.month() == 1);
42 assertTrue (dt.day() == 1);
43 assertTrue (dt.hour() == 0);
44 assertTrue (dt.minute() == 0);
45 assertTrue (dt.second() == 0);
46 assertTrue (dt.millisecond() == 0);
47 assertTrue (dt.dayOfWeek() == 4);
48 assertTrue (dt.julianDay() == 2440587.5);
49 assertTrue (dt.timestamp() == 0);
50
51 ts = Timestamp::fromEpochTime(1000000000);
52 dt = ts; // 2001-09-09 01:46:40 Sunday
53 assertTrue (dt.year() == 2001);
54 assertTrue (dt.month() == 9);
55 assertTrue (dt.day() == 9);
56 assertTrue (dt.hour() == 1);
57 assertTrue (dt.minute() == 46);
58 assertTrue (dt.second() == 40);
59 assertTrue (dt.millisecond() == 0);
60 assertTrue (dt.dayOfWeek() == 0);
61 assertTrue (dt.timestamp().epochTime() == 1000000000);
62 assertEqualDelta (dt.julianDay(), 2452161.574074, 0.000001);
63}
64
65
66void DateTimeTest::testJulian()
67{
68 DateTime dt(2440587.5); // unix epoch as Julian day
69 assertTrue (dt.year() == 1970);
70 assertTrue (dt.month() == 1);
71 assertTrue (dt.day() == 1);
72 assertTrue (dt.hour() == 0);
73 assertTrue (dt.minute() == 0);
74 assertTrue (dt.second() == 0);
75 assertTrue (dt.millisecond() == 0);
76 assertTrue (dt.dayOfWeek() == 4);
77 assertTrue (dt.julianDay() == 2440587.5);
78 assertTrue (dt.timestamp() == 0);
79
80 dt = 2299160.5; // 1582-10-15 00:00:00 (first day of Gregorian reform, UTC base)
81 assertTrue (dt.year() == 1582);
82 assertTrue (dt.month() == 10);
83 assertTrue (dt.day() == 15);
84 assertTrue (dt.hour() == 0);
85 assertTrue (dt.minute() == 0);
86 assertTrue (dt.second() == 0);
87 assertTrue (dt.millisecond() == 0);
88 assertTrue (dt.dayOfWeek() == 5);
89 assertTrue (dt.julianDay() == 2299160.5);
90
91 dt = 0.0; // -4713-11-24 12:00:00 (Gregorian date of Julian day reference)
92 assertTrue (dt.year() == -4713);
93 assertTrue (dt.month() == 11);
94 assertTrue (dt.day() == 24);
95 assertTrue (dt.hour() == 12);
96 assertTrue (dt.minute() == 0);
97 assertTrue (dt.second() == 0);
98 assertTrue (dt.millisecond() == 0);
99 assertTrue (dt.dayOfWeek() == 1);
100 assertTrue (dt.julianDay() == 0);
101
102 // Test that we can represent down to the microsecond.
103 dt = DateTime(2010, 1, 31, 17, 30, 15, 800, 3);
104
105 assertTrue (dt.year() == 2010);
106 assertTrue (dt.month() == 1);
107 assertTrue (dt.day() == 31);
108 assertTrue (dt.hour() == 17);
109 assertTrue (dt.minute() == 30);
110 assertTrue (dt.second() == 15);
111 assertTrue (dt.millisecond() == 800);
112 assertTrue (dt.microsecond() == 3);
113}
114
115
116void DateTimeTest::testGregorian()
117{
118 DateTime dt(1970, 1, 1);
119 assertTrue (dt.year() == 1970);
120 assertTrue (dt.month() == 1);
121 assertTrue (dt.day() == 1);
122 assertTrue (dt.hour() == 0);
123 assertTrue (dt.minute() == 0);
124 assertTrue (dt.second() == 0);
125 assertTrue (dt.millisecond() == 0);
126 assertTrue (dt.dayOfWeek() == 4);
127 assertTrue (dt.julianDay() == 2440587.5);
128 assertTrue (dt.timestamp() == 0);
129
130 dt.assign(2001, 9, 9, 1, 46, 40);
131 assertTrue (dt.year() == 2001);
132 assertTrue (dt.month() == 9);
133 assertTrue (dt.day() == 9);
134 assertTrue (dt.hour() == 1);
135 assertTrue (dt.minute() == 46);
136 assertTrue (dt.second() == 40);
137 assertTrue (dt.millisecond() == 0);
138 assertTrue (dt.dayOfWeek() == 0);
139 assertTrue (dt.timestamp().epochTime() == 1000000000);
140 assertEqualDelta (dt.julianDay(), 2452161.574074, 0.000001);
141}
142
143
144void DateTimeTest::testConversions()
145{
146 DateTime dt1(2005, 1, 28, 14, 24, 44, 234);
147 Timestamp ts1 = dt1.timestamp();
148 DateTime dt2(ts1);
149 Timestamp ts2 = dt2.timestamp();
150 DateTime dt3;
151 dt3 = dt1;
152 Timestamp ts3 = dt3.timestamp();
153 DateTime dt4(dt2);
154 Timestamp ts4 = dt4.timestamp();
155
156 assertTrue (ts1 == ts2);
157 assertTrue (ts2 == ts3);
158 assertTrue (ts3 == ts4);
159
160 assertTrue (dt2.year() == 2005);
161 assertTrue (dt2.month() == 1);
162 assertTrue (dt2.day() == 28);
163 assertTrue (dt2.hour() == 14);
164 assertTrue (dt2.minute() == 24);
165 assertTrue (dt2.second() == 44);
166 assertTrue (dt2.millisecond() == 234);
167 assertTrue (dt2.dayOfWeek() == 5);
168}
169
170
171void DateTimeTest::testStatics()
172{
173 assertTrue (DateTime::isLeapYear(1984));
174 assertTrue (DateTime::isLeapYear(1988));
175 assertTrue (DateTime::isLeapYear(1992));
176 assertTrue (DateTime::isLeapYear(1996));
177 assertTrue (DateTime::isLeapYear(2000));
178 assertTrue (DateTime::isLeapYear(2400));
179 assertTrue (!DateTime::isLeapYear(1995));
180 assertTrue (!DateTime::isLeapYear(1998));
181 assertTrue (!DateTime::isLeapYear(2001));
182 assertTrue (!DateTime::isLeapYear(1800));
183 assertTrue (!DateTime::isLeapYear(1900));
184
185 assertTrue (DateTime::daysOfMonth(2000, 1) == 31);
186 assertTrue (DateTime::daysOfMonth(2000, 2) == 29);
187 assertTrue (DateTime::daysOfMonth(1999, 2) == 28);
188}
189
190
191void DateTimeTest::testCalcs()
192{
193 DateTime dt1(2005, 1, 1);
194 assertTrue (dt1.dayOfYear() == 1);
195 assertTrue (dt1.week(DateTime::MONDAY) == 0);
196 dt1.assign(2005, 1, 3);
197 assertTrue (dt1.dayOfYear() == 3);
198 assertTrue (dt1.week(DateTime::MONDAY) == 1);
199 dt1.assign(2005, 1, 9);
200 assertTrue (dt1.dayOfYear() == 9);
201 assertTrue (dt1.week(DateTime::MONDAY) == 1);
202 dt1.assign(2005, 1, 10);
203 assertTrue (dt1.dayOfYear() == 10);
204 assertTrue (dt1.week(DateTime::MONDAY) == 2);
205 dt1.assign(2005, 2, 1);
206 assertTrue (dt1.dayOfYear() == 32);
207 assertTrue (dt1.week(DateTime::MONDAY) == 5);
208 dt1.assign(2005, 12, 31);
209 assertTrue (dt1.week(DateTime::MONDAY) == 52);
210 dt1.assign(2007, 1, 1);
211 assertTrue (dt1.week(DateTime::MONDAY) == 1);
212 dt1.assign(2007, 12, 31);
213 assertTrue (dt1.week(DateTime::MONDAY) == 53);
214
215 // Jan 1 is Mon
216 dt1.assign(2001, 1, 1);
217 assertTrue (dt1.week() == 1);
218 dt1.assign(2001, 1, 7);
219 assertTrue (dt1.week() == 1);
220 dt1.assign(2001, 1, 8);
221 assertTrue (dt1.week() == 2);
222 dt1.assign(2001, 1, 21);
223 assertTrue (dt1.week() == 3);
224 dt1.assign(2001, 1, 22);
225 assertTrue (dt1.week() == 4);
226
227 // Jan 1 is Tue
228 dt1.assign(2002, 1, 1);
229 assertTrue (dt1.week() == 1);
230 dt1.assign(2002, 1, 6);
231 assertTrue (dt1.week() == 1);
232 dt1.assign(2002, 1, 7);
233 assertTrue (dt1.week() == 2);
234 dt1.assign(2002, 1, 20);
235 assertTrue (dt1.week() == 3);
236 dt1.assign(2002, 1, 21);
237 assertTrue (dt1.week() == 4);
238
239 // Jan 1 is Wed
240 dt1.assign(2003, 1, 1);
241 assertTrue (dt1.week() == 1);
242 dt1.assign(2003, 1, 5);
243 assertTrue (dt1.week() == 1);
244 dt1.assign(2003, 1, 6);
245 assertTrue (dt1.week() == 2);
246 dt1.assign(2003, 1, 19);
247 assertTrue (dt1.week() == 3);
248 dt1.assign(2003, 1, 20);
249 assertTrue (dt1.week() == 4);
250
251 // Jan 1 is Thu
252 dt1.assign(2004, 1, 1);
253 assertTrue (dt1.week() == 1);
254 dt1.assign(2004, 1, 4);
255 assertTrue (dt1.week() == 1);
256 dt1.assign(2004, 1, 5);
257 assertTrue (dt1.week() == 2);
258 dt1.assign(2004, 1, 18);
259 assertTrue (dt1.week() == 3);
260 dt1.assign(2004, 1, 19);
261 assertTrue (dt1.week() == 4);
262
263 // Jan 1 is Fri
264 dt1.assign(1999, 1, 1);
265 assertTrue (dt1.week() == 0);
266 dt1.assign(1999, 1, 3);
267 assertTrue (dt1.week() == 0);
268 dt1.assign(1999, 1, 4);
269 assertTrue (dt1.week() == 1);
270 dt1.assign(1999, 1, 17);
271 assertTrue (dt1.week() == 2);
272 dt1.assign(1999, 1, 18);
273 assertTrue (dt1.week() == 3);
274
275 // Jan 1 is Sat
276 dt1.assign(2000, 1, 1);
277 assertTrue (dt1.week() == 0);
278 dt1.assign(2000, 1, 2);
279 assertTrue (dt1.week() == 0);
280 dt1.assign(2000, 1, 3);
281 assertTrue (dt1.week() == 1);
282 dt1.assign(2000, 1, 16);
283 assertTrue (dt1.week() == 2);
284 dt1.assign(2000, 1, 17);
285 assertTrue (dt1.week() == 3);
286
287 // Jan 1 is Sun
288 dt1.assign(1995, 1, 1);
289 assertTrue (dt1.week() == 0);
290 dt1.assign(1995, 1, 2);
291 assertTrue (dt1.week() == 1);
292 dt1.assign(1995, 1, 3);
293 assertTrue (dt1.week() == 1);
294 dt1.assign(1995, 1, 15);
295 assertTrue (dt1.week() == 2);
296 dt1.assign(1995, 1, 16);
297 assertTrue (dt1.week() == 3);
298}
299
300
301void DateTimeTest::testAMPM()
302{
303 DateTime dt1(2005, 1, 1, 0, 15, 30);
304 assertTrue (dt1.isAM());
305 assertTrue (!dt1.isPM());
306 assertTrue (dt1.hourAMPM() == 12);
307
308 dt1.assign(2005, 1, 1, 12, 15, 30);
309 assertTrue (!dt1.isAM());
310 assertTrue (dt1.isPM());
311 assertTrue (dt1.hourAMPM() == 12);
312
313 dt1.assign(2005, 1, 1, 13, 15, 30);
314 assertTrue (!dt1.isAM());
315 assertTrue (dt1.isPM());
316 assertTrue (dt1.hourAMPM() == 1);
317}
318
319
320void DateTimeTest::testRelational()
321{
322 DateTime dt1(2005, 1, 1, 0, 15, 30);
323 DateTime dt2(2005, 1, 2, 0, 15, 30);
324 DateTime dt3(dt1);
325
326 assertTrue (dt1 < dt2);
327 assertTrue (dt1 <= dt2);
328 assertTrue (dt2 > dt1);
329 assertTrue (dt2 >= dt1);
330 assertTrue (dt1 != dt2);
331 assertTrue (!(dt1 == dt2));
332
333 assertTrue (dt1 == dt3);
334 assertTrue (!(dt1 != dt3));
335 assertTrue (dt1 >= dt3);
336 assertTrue (dt1 <= dt3);
337 assertTrue (!(dt1 > dt3));
338 assertTrue (!(dt1 < dt3));
339
340 static const struct
341 {
342 int year;
343 int month;
344 int day;
345 } values[] =
346 {
347 { 1, 1, 1 },
348 { 10, 4, 5 },
349 { 100, 6, 7 },
350 { 1000, 8, 9 },
351 { 2000, 1, 31 },
352 { 2002, 7, 4 },
353 { 2002, 12, 31 },
354 { 2003, 1, 1 },
355 { 2003, 1, 2 },
356 { 2003, 8, 5 },
357 { 2003, 8, 6 },
358 { 2003, 8, 7 },
359 { 2004, 9, 3 },
360 { 2004, 9, 4 },
361 };
362
363 const int num_values = sizeof values / sizeof *values;
364 for (int i = 0; i < num_values; ++i)
365 {
366 DateTime v;
367 const DateTime& V = v;
368 v.assign(values[i].year, values[i].month, values[i].day);
369 for (int j = 0; j < num_values; ++j)
370 {
371 DateTime u;
372 const DateTime& U = u;
373 u.assign(values[j].year, values[j].month, values[j].day);
374
375 loop_2_assert (i, j, (j < i) == (U < V));
376 loop_2_assert (i, j, (j <= i) == (U <= V));
377 loop_2_assert (i, j, (j >= i) == (U >= V));
378 loop_2_assert (i, j, (j > i) == (U > V));
379 }
380 }
381}
382
383
384void DateTimeTest::testArithmetics()
385{
386 DateTime dt1(2005, 1, 1, 0, 15, 30);
387 DateTime dt2(2005, 1, 2, 0, 15, 30);
388
389 Timespan s = dt2 - dt1;
390 assertTrue (s.days() == 1);
391
392 DateTime dt3 = dt1 + s;
393 assertTrue (dt3 == dt2);
394
395 dt3 -= s;
396 assertTrue (dt3 == dt1);
397 dt1 += s;
398 assertTrue (dt1 == dt2);
399
400 static const struct
401 {
402 int lineNum; // source line number
403 int year1; // operand/result date1 year
404 int month1; // operand/result date1 month
405 unsigned int day1; // operand/result date1 day
406 int numDays; // operand/result 'int' number of days
407 int year2; // operand/result date2 year
408 int month2; // operand/result date2 month
409 unsigned int day2; // operand/result date2 day
410 } data[] =
411 {
412 // - - - -first- - - - - - - second - - -
413 //line no. year month day numDays year month day
414 //------- ----- ----- ----- ------- ----- ----- -----
415 { __LINE__, 1, 1, 1, 1, 1, 1, 2 },
416 { __LINE__, 10, 2, 28, 1, 10, 3, 1 },
417 { __LINE__, 100, 3, 31, 2, 100, 4, 2 },
418 { __LINE__, 1000, 4, 30, 4, 1000, 5, 4 },
419 { __LINE__, 1000, 6, 1, -31, 1000, 5, 1 },
420 { __LINE__, 1001, 1, 1, -365, 1000, 1, 1 },
421 { __LINE__, 1100, 5, 31, 30, 1100, 6, 30 },
422 { __LINE__, 1200, 6, 30, 32, 1200, 8, 1 },
423 { __LINE__, 1996, 2, 28, 367, 1997, 3, 1 },
424 { __LINE__, 1997, 2, 28, 366, 1998, 3, 1 },
425 { __LINE__, 1998, 2, 28, 365, 1999, 2, 28 },
426 { __LINE__, 1999, 2, 28, 364, 2000, 2, 27 },
427 { __LINE__, 1999, 2, 28, 1096, 2002, 2, 28 },
428 { __LINE__, 2002, 2, 28, -1096, 1999, 2, 28 },
429 };
430
431 const int num_data = sizeof data / sizeof *data;
432 for (int di = 0; di < num_data; ++di)
433 {
434 const int line = data[di].lineNum;
435 const int num_days = data[di].numDays;
436 DateTime x = DateTime(data[di].year1, data[di].month1, data[di].day1);
437 const DateTime& X = x;
438 x += Timespan(num_days, 0, 0, 0, 0);
439 loop_1_assert (line, data[di].year2 == X.year());
440 loop_1_assert (line, data[di].month2 == X.month());
441 loop_1_assert (line, data[di].day2 == X.day());
442 }
443
444 DateTime edgeTime(2014, 9, 16, 0, 0, 0, 0, 10);
445 edgeTime -= Poco::Timespan(11);
446 assertTrue (edgeTime.year() == 2014);
447 assertTrue (edgeTime.month() == 9);
448 assertTrue (edgeTime.day() == 15);
449 assertTrue (edgeTime.hour() == 23);
450 assertTrue (edgeTime.minute() == 59);
451 assertTrue (edgeTime.second() == 59);
452 assertTrue (edgeTime.millisecond() == 999);
453 assertTrue (edgeTime.microsecond() == 999);
454
455 edgeTime.assign(2014, 9, 15, 23, 59, 59, 999, 968);
456 edgeTime += Poco::Timespan(11);
457 assertTrue (edgeTime.year() == 2014);
458 assertTrue (edgeTime.month() == 9);
459 assertTrue (edgeTime.day() == 15);
460 assertTrue (edgeTime.hour() == 23);
461 assertTrue (edgeTime.minute() == 59);
462 assertTrue (edgeTime.second() == 59);
463 assertTrue (edgeTime.millisecond() == 999);
464 assertTrue (edgeTime.microsecond() == 979);
465}
466
467void DateTimeTest::testIncrementDecrement()
468{
469 static const struct
470 {
471 int lineNum; // source line number
472 int year1; // (first) date year
473 int month1; // (first) date month
474 unsigned int day1; // (first) date day
475 int year2; // (second) date year
476 int month2; // (second) date month
477 unsigned int day2; // (second) date day
478 } data[] =
479 {
480 // - - - -first- - - - - - - second - - -
481 //line no. year month day year month day
482 //------- ----- ----- ----- ----- ----- -----
483 { __LINE__, 1, 1, 1, 1, 1, 2 },
484 { __LINE__, 10, 2, 28, 10, 3, 1 },
485 { __LINE__, 100, 3, 31, 100, 4, 1 },
486 { __LINE__, 1000, 4, 30, 1000, 5, 1 },
487 { __LINE__, 1100, 5, 31, 1100, 6, 1 },
488 { __LINE__, 1200, 6, 30, 1200, 7, 1 },
489 { __LINE__, 1300, 7, 31, 1300, 8, 1 },
490 { __LINE__, 1400, 8, 31, 1400, 9, 1 },
491 { __LINE__, 1500, 9, 30, 1500, 10, 1 },
492 { __LINE__, 1600, 10, 31, 1600, 11, 1 },
493 { __LINE__, 1700, 11, 30, 1700, 12, 1 },
494 { __LINE__, 1800, 12, 31, 1801, 1, 1 },
495 { __LINE__, 1996, 2, 28, 1996, 2, 29 },
496 { __LINE__, 1997, 2, 28, 1997, 3, 1 },
497 { __LINE__, 1998, 2, 28, 1998, 3, 1 },
498 { __LINE__, 1999, 2, 28, 1999, 3, 1 },
499 { __LINE__, 2000, 2, 28, 2000, 2, 29 },
500 { __LINE__, 2001, 2, 28, 2001, 3, 1 },
501 { __LINE__, 2004, 2, 28, 2004, 2, 29 },
502 { __LINE__, 2100, 2, 28, 2100, 3, 1 },
503 { __LINE__, 2400, 2, 28, 2400, 2, 29 },
504 };
505
506 const int num_data = sizeof data / sizeof *data;
507 int di;
508
509 for (di = 0; di < num_data; ++di)
510 {
511 const int line = data[di].lineNum;
512 DateTime x = DateTime(data[di].year1, data[di].month1,
513 data[di].day1);
514 // Would do pre-increment of x here.
515 const DateTime& X = x;
516 x = x + Timespan(1,0,0,0,0);
517 DateTime y = x; const DateTime& Y = y;
518
519 loop_1_assert (line, data[di].year2 == X.year());
520 loop_1_assert (line, data[di].month2 == X.month());
521 loop_1_assert (line, data[di].day2 == X.day());
522
523 loop_1_assert (line, data[di].year2 == Y.year());
524 loop_1_assert (line, data[di].month2 == Y.month());
525 loop_1_assert (line, data[di].day2 == Y.day());
526 }
527
528 for (di = 0; di < num_data; ++di)
529 {
530 const int line = data[di].lineNum;
531 DateTime x = DateTime(data[di].year1, data[di].month1, data[di].day1);
532 DateTime x1 = DateTime(data[di].year1, data[di].month1, data[di].day1);
533 DateTime x2 = DateTime(data[di].year2, data[di].month2, data[di].day2);
534 DateTime y = x; const DateTime& Y = y;
535
536 // Would do post increment of x here.
537 const DateTime& X = x;
538 x = x + Timespan(1,0,0,0,0);
539
540 loop_1_assert (line, data[di].year2 == X.year());
541 loop_1_assert (line, data[di].month2 == X.month());
542 loop_1_assert (line, data[di].day2 == X.day());
543 loop_1_assert (line, data[di].year1 == Y.year());
544 loop_1_assert (line, data[di].month1 == Y.month());
545 loop_1_assert (line, data[di].day1 == Y.day());
546 }
547
548 for (di = 0; di < num_data; ++di)
549 {
550 const int line = data[di].lineNum;
551 DateTime x = DateTime(data[di].year2, data[di].month2, data[di].day2);
552 const DateTime& X = x;
553 x = x - Timespan(1,0,0,0,0);
554 DateTime y = x; DateTime Y = y;
555
556 loop_1_assert (line, data[di].year1 == X.year());
557 loop_1_assert (line, data[di].month1 == X.month());
558 loop_1_assert (line, data[di].day1 == X.day());
559
560 loop_1_assert (line, data[di].year1 == Y.year());
561 loop_1_assert (line, data[di].month1 == Y.month());
562 loop_1_assert (line, data[di].day1 == Y.day());
563 }
564
565 for (di = 0; di < num_data; ++di)
566 {
567 const int line = data[di].lineNum;
568 DateTime x1 = DateTime(data[di].year1, data[di].month1, data[di].day1);
569 DateTime x = DateTime(data[di].year2, data[di].month2, data[di].day2);
570 DateTime y = x; DateTime Y = y;
571 const DateTime& X = x;
572 // would post-decrement x here.
573 x = x - Timespan(1,0,0,0,0);
574
575 loop_1_assert (line, data[di].year1 == X.year());
576 loop_1_assert (line, data[di].month1 == X.month());
577 loop_1_assert (line, data[di].day1 == X.day());
578
579 loop_1_assert (line, data[di].year2 == Y.year());
580 loop_1_assert (line, data[di].month2 == Y.month());
581 loop_1_assert (line, data[di].day2 == Y.day());
582 }
583}
584
585
586void DateTimeTest::testSwap()
587{
588 DateTime dt1(2005, 1, 1, 0, 15, 30);
589 DateTime dt2(2005, 1, 2, 0, 15, 30);
590 DateTime dt3(2005, 1, 1, 0, 15, 30);
591 DateTime dt4(2005, 1, 2, 0, 15, 30);
592
593 dt1.swap(dt2);
594 assertTrue (dt2 == dt3);
595 assertTrue (dt1 == dt4);
596}
597
598
599void DateTimeTest::testUsage()
600{
601 DateTime dt1(1776, 7, 4);
602 assertTrue (dt1.year() == 1776);
603 assertTrue (dt1.month() == 7);
604 assertTrue (dt1.day() == 4);
605
606 DateTime dt2(dt1);
607 dt2 += Timespan(6, 0, 0, 0, 0);
608 assertTrue (dt2.year() == 1776);
609 assertTrue (dt2.month() == 7);
610 assertTrue (dt2.day() == 10);
611
612 Timespan span = dt2 - dt1;
613 assertTrue (span.days() == 6);
614
615 // TODO - When adding months and years we need to be
616 // able to specify the end-end convention.
617 // We cannot do this in POCO at the moment.
618}
619
620
621void DateTimeTest::testSetYearDay()
622{
623 static const struct
624 {
625 int d_lineNum; // source line number
626 int d_year; // year under test
627 unsigned int d_day; // day-of-year under test
628 int d_expMonth; // expected month
629 unsigned int d_expDay; // expected day
630 } data[] =
631 {
632 //line no. year dayOfYr exp. month exp. day
633 //------- ----- ------- ---------- --------
634 { __LINE__, 1, 1, 1, 1 },
635 { __LINE__, 1, 2, 1, 2 },
636 { __LINE__, 1, 365, 12, 31 },
637 { __LINE__, 1996, 1, 1, 1 },
638 { __LINE__, 1996, 2, 1, 2 },
639 { __LINE__, 1996, 365, 12, 30 },
640 { __LINE__, 1996, 366, 12, 31 }
641 };
642
643 const int num_data = sizeof data / sizeof *data;
644 for (int di = 0; di < num_data; ++di)
645 {
646 const int line = data[di].d_lineNum;
647 const int year = data[di].d_year;
648 const unsigned int day = data[di].d_day;
649
650 const int exp_month = data[di].d_expMonth;
651 const unsigned int exp_day = data[di].d_expDay;
652 const DateTime r(year, exp_month, exp_day);
653 DateTime x;
654 const DateTime& X = x;
655
656#if 0
657 // TODO - need to be able to assign a day number in the year
658 // but POCO is not able to do this.
659
660 x.assign(year, day);
661
662 // TODO - need to be able to assert with the loop counter
663 // but cppUnit is not able to do this.
664
665 assertTrue (r == x);
666 assertTrue (day == X.dayOfYear());
667#endif
668 }
669
670 static const struct
671 {
672 int d_lineNum; // source line number
673 int d_year; // year under test
674 int d_day; // day-of-year under test
675 int d_exp; // expected status
676 } data2[] =
677 {
678 //line no. year dayOfYr expected value
679 //------- ----- ------- --------------
680 { __LINE__, 1, 1, 1 },
681 { __LINE__, 1, -1, 0 },
682 { __LINE__, 1, 0, 0 },
683 { __LINE__, 1, 365, 1 },
684 { __LINE__, 1, 366, 0 },
685 { __LINE__, 1, 367, 0 },
686 { __LINE__, 0, 0, 0 },
687 { __LINE__, -1, -1, 0 },
688 { __LINE__, 1996, 1, 1 },
689 { __LINE__, 1996, 2, 1 },
690 { __LINE__, 1996, 32, 1 },
691 { __LINE__, 1996, 365, 1 },
692 { __LINE__, 1996, 366, 1 },
693 { __LINE__, 1996, 367, 0 },
694 };
695
696 const int num_data2 = sizeof data2 / sizeof *data2;
697 for (int di = 0; di < num_data2; ++di)
698 {
699 const int line = data2[di].d_lineNum;
700 const int year = data2[di].d_year;
701 const int day = data2[di].d_day;
702 const int exp = data2[di].d_exp;
703 DateTime x;
704 const DateTime& X = x;
705 if (1 == exp)
706 {
707 DateTime r;
708 const DateTime& r2 = r;
709#if 0
710 r.set(year, day);
711#endif
712 }
713 }
714}
715
716
717void DateTimeTest::testIsValid()
718{
719 static const struct
720 {
721 int d_lineNum; // source line number
722 int d_year; // year under test
723 int d_month; // month under test
724 int d_day; // day under test
725 bool d_exp; // expected value
726 } data[] =
727 {
728 //line no. year month day expected value
729 //------- ----- ----- ----- --------------
730 { __LINE__, 0, 0, 0, false },
731 { __LINE__, 1, 1, 0, false },
732 { __LINE__, 1, 0, 1, false },
733 { __LINE__, 0, 1, 1, true },
734 { __LINE__, 1, 1, -1, false },
735 { __LINE__, 1, -1, 1, false },
736 { __LINE__, 2004, 1, 32, false },
737 { __LINE__, 2004, 2, 30, false },
738 { __LINE__, 2004, 3, 32, false },
739 { __LINE__, 2004, 4, 31, false },
740 { __LINE__, 2004, 5, 32, false },
741 { __LINE__, 2004, 6, 31, false },
742 { __LINE__, 2004, 7, 32, false },
743 { __LINE__, 2004, 8, 32, false },
744 { __LINE__, 2004, 9, 31, false },
745 { __LINE__, 2004, 10, 32, false },
746 { __LINE__, 2004, 11, 31, false },
747 { __LINE__, 2004, 12, 32, false },
748 { __LINE__, 0, 12, 31, true },
749 { __LINE__, 0, 2, 29, true },
750 { __LINE__, 1, 1, 1, true },
751 { __LINE__, 2010, 1, 2, true },
752 { __LINE__, 2011, 2, 5, true },
753 { __LINE__, 2012, 3, 10, true },
754 { __LINE__, 2013, 4, 17, true },
755 { __LINE__, 2014, 5, 23, true },
756 { __LINE__, 1600, 2, 29, true },
757 { __LINE__, 1700, 2, 29, false },
758 { __LINE__, 1800, 2, 29, false },
759 { __LINE__, 1900, 2, 29, false },
760 { __LINE__, 2000, 2, 29, true },
761 { __LINE__, 2100, 2, 29, false },
762 };
763
764 const int num_data = sizeof data / sizeof *data;
765 for (int di = 0; di < num_data; ++di)
766 {
767 const int line = data[di].d_lineNum;
768 const int year = data[di].d_year;
769 const int month = data[di].d_month;
770 const int day = data[di].d_day;
771 const bool exp = data[di].d_exp;
772
773 bool isValid = DateTime::isValid(year, month, day);
774 loop_1_assert (line, exp == isValid);
775 }
776}
777
778
779void DateTimeTest::testDayOfWeek()
780{
781 typedef DateTime::DaysOfWeek DOW;
782
783 static const struct
784 {
785 int d_lineNum; // source line number
786 int d_year; // year under test
787 int d_month; // month under test
788 int d_day; // day under test
789 DOW d_expDay; // number of days to be added
790 } data[] =
791 {
792 //Line no. year month day expDay
793 //------- ----- ----- ----- -------
794 { __LINE__, 1600, 1, 1, DateTime::SATURDAY },
795 { __LINE__, 1600, 1, 2, DateTime::SUNDAY },
796 { __LINE__, 1600, 1, 3, DateTime::MONDAY },
797 { __LINE__, 1600, 1, 4, DateTime::TUESDAY },
798 { __LINE__, 1600, 1, 5, DateTime::WEDNESDAY },
799 { __LINE__, 1600, 1, 6, DateTime::THURSDAY },
800 { __LINE__, 1600, 1, 7, DateTime::FRIDAY },
801 { __LINE__, 1600, 1, 8, DateTime::SATURDAY },
802 { __LINE__, 1752, 8, 27, DateTime::SUNDAY },
803 { __LINE__, 1752, 8, 28, DateTime::MONDAY },
804 { __LINE__, 1752, 8, 29, DateTime::TUESDAY },
805 { __LINE__, 1752, 8, 30, DateTime::WEDNESDAY },
806 { __LINE__, 1752, 8, 31, DateTime::THURSDAY },
807 { __LINE__, 1752, 9, 1, DateTime::FRIDAY },
808 { __LINE__, 1752, 9, 2, DateTime::SATURDAY },
809 { __LINE__, 1752, 9, 14, DateTime::THURSDAY },
810 { __LINE__, 1752, 9, 15, DateTime::FRIDAY },
811 { __LINE__, 1752, 9, 16, DateTime::SATURDAY },
812 { __LINE__, 1752, 9, 17, DateTime::SUNDAY },
813 { __LINE__, 1752, 9, 18, DateTime::MONDAY },
814 { __LINE__, 1752, 9, 19, DateTime::TUESDAY },
815 { __LINE__, 1999, 12, 28, DateTime::TUESDAY },
816 { __LINE__, 1999, 12, 29, DateTime::WEDNESDAY },
817 { __LINE__, 1999, 12, 30, DateTime::THURSDAY },
818 { __LINE__, 1999, 12, 31, DateTime::FRIDAY },
819 { __LINE__, 2000, 1, 1, DateTime::SATURDAY },
820 { __LINE__, 2000, 1, 2, DateTime::SUNDAY },
821 { __LINE__, 2000, 1, 3, DateTime::MONDAY },
822 { __LINE__, 2000, 1, 4, DateTime::TUESDAY },
823 };
824
825 const int num_data = sizeof data / sizeof *data;
826 for (int di = 0; di < num_data ; ++di)
827 {
828 const int line = data[di].d_lineNum;
829 DateTime x = DateTime(data[di].d_year, data[di].d_month, data[di].d_day);
830 const DateTime& X = x;
831 loop_1_assert (line, data[di].d_expDay == X.dayOfWeek());
832 }
833}
834
835
836void DateTimeTest::testUTC()
837{
838 DateTime dt(2007, 3, 5, 12, 30, 00);
839
840 assertTrue (dt.hour() == 12);
841 dt.makeUTC(3600);
842 assertTrue (dt.hour() == 11);
843 dt.makeLocal(3600);
844 assertTrue (dt.hour() == 12);
845}
846
847
848void DateTimeTest::testLeapSeconds()
849{
850 DateTime dt1(2015, 6, 30, 23, 59, 60);
851 DateTime dt2(2015, 7, 1, 0, 0, 0);
852
853 assertTrue (dt1 == dt2);
854}
855
856
857void DateTimeTest::testTM()
858{
859 time_t now;
860 time(&now);
861 tm* pTM = gmtime(&now);
862 DateTime dt(*pTM);
863 assertTrue (dt.second() == pTM->tm_sec);
864 assertTrue (dt.minute() == pTM->tm_min);
865 assertTrue (dt.hour() == pTM->tm_hour);
866 assertTrue (dt.day() == pTM->tm_mday);
867 assertTrue (dt.month() == pTM->tm_mon + 1);
868 assertTrue (dt.year() == pTM->tm_year + 1900);
869 assertTrue (dt.dayOfWeek() == pTM->tm_wday);
870 assertTrue (dt.dayOfYear() == pTM->tm_yday + 1);
871}
872
873
874void DateTimeTest::setUp()
875{
876}
877
878
879void DateTimeTest::tearDown()
880{
881}
882
883
884CppUnit::Test* DateTimeTest::suite()
885{
886 CppUnit::TestSuite* pSuite = new CppUnit::TestSuite("DateTimeTest");
887
888 CppUnit_addTest(pSuite, DateTimeTest, testTimestamp);
889 CppUnit_addTest(pSuite, DateTimeTest, testJulian);
890 CppUnit_addTest(pSuite, DateTimeTest, testGregorian);
891 CppUnit_addTest(pSuite, DateTimeTest, testConversions);
892 CppUnit_addTest(pSuite, DateTimeTest, testStatics);
893 CppUnit_addTest(pSuite, DateTimeTest, testCalcs);
894 CppUnit_addTest(pSuite, DateTimeTest, testAMPM);
895 CppUnit_addTest(pSuite, DateTimeTest, testRelational);
896 CppUnit_addTest(pSuite, DateTimeTest, testArithmetics);
897 CppUnit_addTest(pSuite, DateTimeTest, testSwap);
898
899 CppUnit_addTest(pSuite, DateTimeTest, testUsage);
900 CppUnit_addTest(pSuite, DateTimeTest, testSetYearDay);
901 CppUnit_addTest(pSuite, DateTimeTest, testIsValid);
902 CppUnit_addTest(pSuite, DateTimeTest, testDayOfWeek);
903 CppUnit_addTest(pSuite, DateTimeTest, testIncrementDecrement);
904 CppUnit_addTest(pSuite, DateTimeTest, testUTC);
905 CppUnit_addTest(pSuite, DateTimeTest, testLeapSeconds);
906 CppUnit_addTest(pSuite, DateTimeTest, testTM);
907
908 return pSuite;
909}
910