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 | |
20 | using Poco::Timestamp; |
21 | using Poco::DateTime; |
22 | using Poco::Timespan; |
23 | using Poco::AssertionViolationException; |
24 | |
25 | |
26 | DateTimeTest::DateTimeTest(const std::string& rName): CppUnit::TestCase(rName) |
27 | { |
28 | } |
29 | |
30 | |
31 | DateTimeTest::~DateTimeTest() |
32 | { |
33 | } |
34 | |
35 | |
36 | void 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 | |
66 | void 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 | |
116 | void 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 | |
144 | void 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 | |
171 | void 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 | |
191 | void 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 | |
301 | void 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 | |
320 | void 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 | |
384 | void 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 | |
467 | void 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 | |
586 | void 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 | |
599 | void 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 | |
621 | void 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 | |
717 | void 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 | |
779 | void 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 | |
836 | void 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 | |
848 | void 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 | |
857 | void 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 | |
874 | void DateTimeTest::setUp() |
875 | { |
876 | } |
877 | |
878 | |
879 | void DateTimeTest::tearDown() |
880 | { |
881 | } |
882 | |
883 | |
884 | CppUnit::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 | |