add precautions for old glibc
[libi2ncommon] / test / test_timefunc.cpp
CommitLineData
0e23f538
TJ
1/*
2The software in this package is distributed under the GNU General
3Public License version 2 (with a special exception described below).
4
5A copy of GNU General Public License (GPL) is included in this distribution,
6in the file COPYING.GPL.
7
8As a special exception, if other files instantiate templates or use macros
9or inline functions from this file, or you compile this file and link it
10with other works to produce a work based on this file, this file
11does not by itself cause the resulting work to be covered
12by the GNU General Public License.
13
14However the source code for this file must still be made available
15in accordance with section (3) of the GNU General Public License.
16
17This exception does not invalidate any other reasons why a work based
18on this file might be covered by the GNU General Public License.
19*/
8d2b7645
TJ
20/** @file
21 * @brief unit test for time related functions.
22 *
23 * @copyright Copyright © 2001-2008 by Intra2net AG
8d2b7645
TJ
24 *
25 */
78e6a1b2
PG
26#include <features.h>
27#if (__GLIBC__ <= 2) && (__GLIBC_MINOR__ < 23)
28/*
29 * Ancient glibc (pre 2015) has a defective implementation of strptime(3)
30 * that doesn’t handle the ‘Z’ modifier of ISO8601 to indicate UTC. It also
31 * parses fractional timezones only partially so e. g. “+11:11” is treated
32 * as “+1100”.
33 */
34# define GLIBC_STRPTIME_LACKS_Z
35#endif
8d2b7645 36
9fe0853b
TJ
37#define BOOST_TEST_DYN_LINK
38#include <boost/test/unit_test.hpp>
8d2b7645
TJ
39
40#include <timefunc.hxx>
41#include <filefunc.hxx>
42
96d0be2e 43#include <unistd.h>
9fe0853b 44#include <set>
ccbeb66c 45#include <iostream>
96d0be2e 46
8d2b7645
TJ
47using namespace std;
48using namespace I2n;
8047e088 49using namespace I2n::Time;
8d2b7645 50
9fe0853b 51class TestTimeFuncFixture
8d2b7645 52{
8d2b7645 53protected:
8d2b7645 54 typedef std::list< std::string > StringList;
8d2b7645 55 std::set<std::string> used_check_files;
ccbeb66c 56 std::string tz; /* save and restore TZ from envp */
8d2b7645
TJ
57
58 std::string get_check_file_path(std::string tag)
59 {
60 std::string result;
61 result= "__unittest__" + tag + ".dat";
62 used_check_files.insert(result);
63 return result;
64 } // eo get_check_file_path
65
8d2b7645
TJ
66 void remove_check_files()
67 {
68 for (std::set<std::string>::iterator it= used_check_files.begin();
69 it != used_check_files.end();
70 ++it)
71 {
72 std::string filepath(*it);
73 if (path_exists(filepath))
74 {
75 unlink(filepath);
76 }
77 //TODO
78 }
79 used_check_files.clear();
80 } // eo remove_check_files
81
8dce1f31 82 void set_tz (const std::string &tzname)
ccbeb66c
PG
83 {
84 errno = 0;
8dce1f31 85 if (setenv ("TZ", tzname.c_str (), 1) == -1)
ccbeb66c
PG
86 {
87 std::cerr
8dce1f31 88 << "error setting environment 'TZ': [" << tzname << "]"
ccbeb66c
PG
89 << std::endl
90 ;
91 return;
92 }
93
94 tzset ();
95 }
96
8dce1f31
PG
97 inline void set_utc (void)
98 {
99 this->set_tz ("UTC");
100 }
101
8d2b7645 102public:
9fe0853b 103 TestTimeFuncFixture()
ccbeb66c 104 : tz (secure_getenv ("TZ") ?: "")
9fe0853b
TJ
105 {
106 }
107
108 ~TestTimeFuncFixture()
109 {
110 remove_check_files();
ccbeb66c
PG
111
112 errno = 0;
113 if (setenv ("TZ", this->tz.c_str (), 1) == -1)
114 {
115 std::cerr
116 << "error cleaning up environment 'TZ': [" << this->tz << "]"
117 << std::endl
118 ;
119 }
120 else
121 {
122 tzset();
123 }
9fe0853b
TJ
124 }
125};
8d2b7645 126
9fe0853b 127BOOST_FIXTURE_TEST_SUITE(TestTimeFunc, TestTimeFuncFixture)
8d2b7645 128
9fe0853b
TJ
129BOOST_AUTO_TEST_CASE(AddIntervalsDisjoint)
130{
131 Intervals intervals;
8d2b7645 132
9fe0853b
TJ
133 intervals.add( Interval( 10, 100 ) );
134 intervals.add( Interval( 600, 620 ) );
8d2b7645 135
9fe0853b
TJ
136 BOOST_CHECK_EQUAL( false, intervals.empty() );
137 BOOST_CHECK_EQUAL( 2u, intervals.size() );
8d2b7645 138
9fe0853b
TJ
139 BOOST_CHECK_EQUAL( 10u, intervals.front().lower_bound() );
140 BOOST_CHECK_EQUAL( 100u, intervals.front().upper_bound() );
8d2b7645 141
9fe0853b
TJ
142 BOOST_CHECK_EQUAL( 600u, intervals.back().lower_bound() );
143 BOOST_CHECK_EQUAL( 620u, intervals.back().upper_bound() );
144} // eo AddIntervalsDisjoint()
8d2b7645
TJ
145
146
147
9fe0853b
TJ
148BOOST_AUTO_TEST_CASE(AddIntervalsInclude)
149{
150 Intervals intervals;
8d2b7645 151
9fe0853b
TJ
152 intervals.add( Interval( 10, 100 ) );
153 intervals.add( Interval( 10, 80 ) );
8d2b7645 154
9fe0853b
TJ
155 BOOST_CHECK_EQUAL( false, intervals.empty() );
156 BOOST_CHECK_EQUAL( 1u, intervals.size() );
8d2b7645 157
9fe0853b
TJ
158 BOOST_CHECK_EQUAL( 10u, intervals.front().lower_bound() );
159 BOOST_CHECK_EQUAL( 100u, intervals.front().upper_bound() );
160 BOOST_CHECK_EQUAL( false, intervals.front().changed() );
161} // eo AddIntervalsInclude()
8d2b7645
TJ
162
163
164
9fe0853b
TJ
165BOOST_AUTO_TEST_CASE(AddIntervalsEmbrace)
166{
167 Intervals intervals;
8d2b7645 168
9fe0853b
TJ
169 intervals.add( Interval( 10, 100 ) );
170 intervals.add( Interval( 5, 120 ) );
8d2b7645 171
9fe0853b
TJ
172 BOOST_CHECK_EQUAL( false, intervals.empty() );
173 BOOST_CHECK_EQUAL( 1u, intervals.size() );
8d2b7645 174
9fe0853b
TJ
175 BOOST_CHECK_EQUAL( 5u, intervals.front().lower_bound() );
176 BOOST_CHECK_EQUAL( 120u, intervals.front().upper_bound() );
177 BOOST_CHECK_EQUAL( true, intervals.front().changed() );
178} // eo AddIntervalsEmbrace()
8d2b7645
TJ
179
180
181
9fe0853b
TJ
182BOOST_AUTO_TEST_CASE(AddIntervalsJoin1)
183{
184 Intervals intervals;
8d2b7645 185
9fe0853b
TJ
186 intervals.add( Interval( 10, 100 ) );
187 intervals.add( Interval( 60, 120 ) );
8d2b7645 188
9fe0853b
TJ
189 BOOST_CHECK_EQUAL( false, intervals.empty() );
190 BOOST_CHECK_EQUAL( 1u, intervals.size() );
8d2b7645 191
9fe0853b
TJ
192 BOOST_CHECK_EQUAL( 10u, intervals.front().lower_bound() );
193 BOOST_CHECK_EQUAL( 120u, intervals.front().upper_bound() );
194 BOOST_CHECK_EQUAL( true, intervals.front().changed() );
195} // eo AddIntervalsJoin1()
8d2b7645
TJ
196
197
198
9fe0853b
TJ
199BOOST_AUTO_TEST_CASE(AddIntervalsJoin1b)
200{
201 Intervals intervals;
8d2b7645 202
9fe0853b
TJ
203 intervals.add( Interval( 10, 100 ) );
204 intervals.add( Interval( 100, 120 ) );
8d2b7645 205
9fe0853b
TJ
206 BOOST_CHECK_EQUAL( false, intervals.empty() );
207 BOOST_CHECK_EQUAL( 1u, intervals.size() );
8d2b7645 208
9fe0853b
TJ
209 BOOST_CHECK_EQUAL( 10u, intervals.front().lower_bound() );
210 BOOST_CHECK_EQUAL( 120u, intervals.front().upper_bound() );
211 BOOST_CHECK_EQUAL( true, intervals.front().changed() );
212} // eo AddIntervalsJoin1b()
8d2b7645
TJ
213
214
215
9fe0853b
TJ
216BOOST_AUTO_TEST_CASE(AddIntervalsJoin2)
217{
218 Intervals intervals;
8d2b7645 219
9fe0853b
TJ
220 intervals.add( Interval( 10, 100 ) );
221 intervals.add( Interval( 200, 250 ) );
8d2b7645 222
9fe0853b
TJ
223 BOOST_CHECK_EQUAL( false, intervals.empty() );
224 BOOST_CHECK_EQUAL( 2u, intervals.size() );
8d2b7645 225
9fe0853b
TJ
226 BOOST_CHECK_EQUAL( 10u, intervals.front().lower_bound() );
227 BOOST_CHECK_EQUAL( 100u, intervals.front().upper_bound() );
228 BOOST_CHECK_EQUAL( 200u, intervals.back().lower_bound() );
229 BOOST_CHECK_EQUAL( 250u, intervals.back().upper_bound() );
8d2b7645 230
9fe0853b
TJ
231 // now add the gap; the intervals should collapse to one covering all:
232 intervals.add( Interval(100, 200) );
8d2b7645 233
9fe0853b
TJ
234 BOOST_CHECK_EQUAL( false, intervals.empty() );
235 BOOST_CHECK_EQUAL( 1u, intervals.size() );
8d2b7645 236
9fe0853b
TJ
237 BOOST_CHECK_EQUAL( 10u, intervals.front().lower_bound() );
238 BOOST_CHECK_EQUAL( 250u, intervals.front().upper_bound() );
239 BOOST_CHECK_EQUAL( true, intervals.front().changed() );
240} // eo AddIntervalsJoin2()
8d2b7645
TJ
241
242
243
9fe0853b
TJ
244BOOST_AUTO_TEST_CASE(SubIntervalsDisjoint)
245{
246 Intervals intervals;
8d2b7645 247
9fe0853b
TJ
248 intervals.add( Interval(10, 100) );
249 intervals.sub( Interval(0, 10) );
8d2b7645 250
9fe0853b
TJ
251 BOOST_CHECK_EQUAL( false, intervals.empty() );
252 BOOST_CHECK_EQUAL( 1u, intervals.size() );
8d2b7645 253
9fe0853b
TJ
254 BOOST_CHECK_EQUAL( 10u, intervals.front().lower_bound() );
255 BOOST_CHECK_EQUAL( 100u, intervals.front().upper_bound() );
256 BOOST_CHECK_EQUAL( false, intervals.front().changed() );
257} // eo SubIntervalsDisjoint()
8d2b7645
TJ
258
259
260
9fe0853b
TJ
261BOOST_AUTO_TEST_CASE(SubIntervalsExact)
262{
263 Intervals intervals;
8d2b7645 264
9fe0853b
TJ
265 intervals.add( Interval(10, 100) );
266 intervals.sub( Interval(10, 100) );
8d2b7645 267
9fe0853b
TJ
268 BOOST_CHECK_EQUAL( true, intervals.empty() );
269 BOOST_CHECK_EQUAL( 0u, intervals.size() );
270} // eo SubIntervalsExact()
8d2b7645
TJ
271
272
273
9fe0853b
TJ
274BOOST_AUTO_TEST_CASE(SubIntervalsSplit1)
275{
276 Intervals intervals;
8d2b7645 277
9fe0853b
TJ
278 intervals.add( Interval(10, 100) );
279 intervals.sub( Interval(20, 40) );
8d2b7645 280
9fe0853b
TJ
281 BOOST_CHECK_EQUAL( false, intervals.empty() );
282 BOOST_CHECK_EQUAL( 2u, intervals.size() );
8d2b7645 283
9fe0853b
TJ
284 BOOST_CHECK_EQUAL( 10u, intervals.front().lower_bound() );
285 BOOST_CHECK_EQUAL( 20u, intervals.front().upper_bound() );
8d2b7645 286
9fe0853b
TJ
287 BOOST_CHECK_EQUAL( 40u, intervals.back().lower_bound() );
288 BOOST_CHECK_EQUAL( 100u, intervals.back().upper_bound() );
289 BOOST_CHECK_EQUAL( false, intervals.front().changed() );
290 BOOST_CHECK_EQUAL( true, intervals.back().changed() );
291} // eo SubIntervalsSplit1()
8d2b7645
TJ
292
293
9fe0853b
TJ
294BOOST_AUTO_TEST_CASE(SubIntervalsCutFront)
295{
296 Intervals intervals;
8d2b7645 297
9fe0853b
TJ
298 intervals.add( Interval(10, 100) );
299 intervals.sub( Interval(10, 20) );
8d2b7645 300
9fe0853b
TJ
301 BOOST_CHECK_EQUAL( false, intervals.empty() );
302 BOOST_CHECK_EQUAL( 1u, intervals.size() );
8d2b7645 303
9fe0853b
TJ
304 BOOST_CHECK_EQUAL( 20u, intervals.front().lower_bound() );
305 BOOST_CHECK_EQUAL( 100u, intervals.front().upper_bound() );
306 BOOST_CHECK_EQUAL( true, intervals.front().changed() );
307} // eo SubIntervalsCutFront()
8d2b7645
TJ
308
309
9fe0853b
TJ
310BOOST_AUTO_TEST_CASE(SubIntervalsCutBack)
311{
312 Intervals intervals;
8d2b7645 313
9fe0853b
TJ
314 intervals.add( Interval(10, 100) );
315 intervals.sub( Interval(87, 100) );
8d2b7645 316
9fe0853b
TJ
317 BOOST_CHECK_EQUAL( false, intervals.empty() );
318 BOOST_CHECK_EQUAL( 1u, intervals.size() );
8d2b7645 319
9fe0853b
TJ
320 BOOST_CHECK_EQUAL( 10u, intervals.front().lower_bound() );
321 BOOST_CHECK_EQUAL( 87u, intervals.front().upper_bound() );
322 BOOST_CHECK_EQUAL( true, intervals.front().changed() );
323} // eo SubIntervalsCutBack()
8d2b7645
TJ
324
325
326
9fe0853b
TJ
327BOOST_AUTO_TEST_CASE(SubIntervalsCutMore)
328{
329 Intervals intervals;
8d2b7645 330
9fe0853b
TJ
331 intervals.add( Interval( 10, 100) );
332 intervals.add( Interval(110, 200) );
333 intervals.add( Interval(210, 300) );
8d2b7645 334
9fe0853b
TJ
335 // this should remove the first 2 intervals and cut the third:
336 intervals.sub( Interval(8, 220) );
8d2b7645 337
9fe0853b
TJ
338 BOOST_CHECK_EQUAL( false, intervals.empty() );
339 BOOST_CHECK_EQUAL( 1u, intervals.size() );
8d2b7645 340
9fe0853b
TJ
341 BOOST_CHECK_EQUAL( 220u, intervals.front().lower_bound() );
342 BOOST_CHECK_EQUAL( 300u, intervals.front().upper_bound() );
343 BOOST_CHECK_EQUAL( true, intervals.front().changed() );
344} // eo SubIntervalsCutMore()
8d2b7645
TJ
345
346
9fe0853b
TJ
347BOOST_AUTO_TEST_CASE(IntervalComparisons)
348{
349 Intervals intervals1;
350 Intervals intervals2;
8d2b7645 351
9fe0853b 352 intervals1.add( Interval( 10, 120) );
8d2b7645 353
9fe0853b
TJ
354 intervals2.add( Interval( 10, 110 ) );
355 intervals2.add( Interval( 100, 120 ) );
8d2b7645 356
9fe0853b 357 BOOST_CHECK_EQUAL( 1u, intervals2.size() );
8d2b7645 358
9fe0853b
TJ
359 BOOST_CHECK( intervals1 == intervals2 );
360 BOOST_CHECK_EQUAL( true, intervals1.contains( intervals2 ));
361 BOOST_CHECK_EQUAL( true, intervals2.contains( intervals1 ));
8d2b7645 362
9fe0853b 363 intervals2.sub( Interval( 40, 50) );
8d2b7645 364
9fe0853b
TJ
365 BOOST_CHECK( intervals1 != intervals2 );
366 BOOST_CHECK_EQUAL( true, intervals1.contains( intervals2 ));
367 BOOST_CHECK_EQUAL( false, intervals2.contains( intervals1 ));
368} // eo IntervalComparisons()
8d2b7645 369
96d0be2e
TJ
370
371
9fe0853b
TJ
372BOOST_AUTO_TEST_CASE(MonotonicClock)
373{
374 long sec0, nsec0;
375 long sec1, nsec1;
96d0be2e 376
9fe0853b
TJ
377 bool res = monotonic_clock_gettime(sec0,nsec0);
378 BOOST_CHECK_EQUAL( true, res );
96d0be2e 379
9fe0853b
TJ
380 usleep(250000);
381 res= monotonic_clock_gettime(sec1,nsec1);
382 BOOST_CHECK_EQUAL( true, res);
96d0be2e 383
9fe0853b
TJ
384 long delta_sec = sec1 - sec0;
385 long delta_nsec= nsec1 - nsec0;
96d0be2e 386
9fe0853b 387 long delta_millisec= ( delta_nsec / 1000000L) + delta_sec * 1000L;
96d0be2e 388
9fe0853b
TJ
389 BOOST_CHECK( delta_millisec >= 250 - /*fuzz*/ 1);
390 BOOST_CHECK( delta_millisec < 300 );
391} // eo MonotonicClock()
96d0be2e 392
9fe0853b
TJ
393BOOST_AUTO_TEST_CASE(WeekInvalid)
394{
395 Week week("99999999");
396 BOOST_CHECK_EQUAL(false, week.is_valid());
397 BOOST_CHECK_EQUAL(string(""), week.get_displaystring());
398}
8047e088 399
9fe0853b
TJ
400BOOST_AUTO_TEST_CASE(WeekDisplayString1)
401{
402 Week week("");
403 BOOST_CHECK_EQUAL(true, week.is_valid());
404 BOOST_CHECK_EQUAL(string(""), week.get_displaystring());
405}
8047e088 406
9fe0853b
TJ
407BOOST_AUTO_TEST_CASE(WeekDisplayString2)
408{
409 Week week("0123456");
410 BOOST_CHECK_EQUAL(true, week.is_valid());
411 BOOST_CHECK_EQUAL(string("Mon-Sun"), week.get_displaystring());
412}
8047e088 413
9fe0853b
TJ
414BOOST_AUTO_TEST_CASE(WeekDisplayString3)
415{
416 Week week("123456");
417 BOOST_CHECK_EQUAL(true, week.is_valid());
418 BOOST_CHECK_EQUAL(string("Mon-Sat"), week.get_displaystring());
419}
8047e088 420
9fe0853b
TJ
421BOOST_AUTO_TEST_CASE(WeekDisplayString4)
422{
423 Week week("012345");
424 BOOST_CHECK_EQUAL(true, week.is_valid());
425 BOOST_CHECK_EQUAL(string("Mon-Fri, Sun"), week.get_displaystring());
426}
8047e088 427
9fe0853b
TJ
428BOOST_AUTO_TEST_CASE(WeekDisplayString5)
429{
430 Week week("1256");
431 BOOST_CHECK_EQUAL(true, week.is_valid());
432 BOOST_CHECK_EQUAL(string("Mon, Tue, Fri, Sat"), week.get_displaystring());
433}
8047e088 434
9fe0853b
TJ
435BOOST_AUTO_TEST_CASE(WeekDisplayString6)
436{
437 Week week("0246");
438 BOOST_CHECK_EQUAL(true, week.is_valid());
439 BOOST_CHECK_EQUAL(string("Tue, Thu, Sat, Sun"), week.get_displaystring());
440}
96d0be2e 441
9fe0853b
TJ
442BOOST_AUTO_TEST_CASE(WeekDisplayString7)
443{
444 Week week("135");
445 BOOST_CHECK_EQUAL(true, week.is_valid());
446 BOOST_CHECK_EQUAL(string("Mon, Wed, Fri"), week.get_displaystring());
447}
8047e088 448
9fe0853b
TJ
449BOOST_AUTO_TEST_CASE(WeekDisplayString8)
450{
451 Week week("15");
452 BOOST_CHECK_EQUAL(true, week.is_valid());
453 BOOST_CHECK_EQUAL(string("Mon, Fri"), week.get_displaystring());
454}
8047e088 455
9fe0853b
TJ
456BOOST_AUTO_TEST_CASE(WeekDisplayString9)
457{
458 Week week("06");
459 BOOST_CHECK_EQUAL(true, week.is_valid());
460 BOOST_CHECK_EQUAL(string("Sat, Sun"), week.get_displaystring());
461}
8047e088 462
9fe0853b
TJ
463BOOST_AUTO_TEST_CASE(WeekDisplayString10)
464{
465 Week week("056");
466 BOOST_CHECK_EQUAL(true, week.is_valid());
467 BOOST_CHECK_EQUAL(string("Fri-Sun"), week.get_displaystring());
468}
8047e088 469
9fe0853b
TJ
470BOOST_AUTO_TEST_CASE(WeekDisplayString11)
471{
472 Week week("0");
473 BOOST_CHECK_EQUAL(true, week.is_valid());
474 BOOST_CHECK_EQUAL(string("Sun"), week.get_displaystring());
475}
8047e088 476
9fe0853b
TJ
477BOOST_AUTO_TEST_CASE(WeekDisplayString12)
478{
479 Week week("6");
480 BOOST_CHECK_EQUAL(true, week.is_valid());
481 BOOST_CHECK_EQUAL(string("Sat"), week.get_displaystring());
482}
8047e088 483
9fe0853b
TJ
484BOOST_AUTO_TEST_CASE(WeekDisplayString13)
485{
486 Week week("123");
487 BOOST_CHECK_EQUAL(true, week.is_valid());
488 BOOST_CHECK_EQUAL(string("Mon-Wed"), week.get_displaystring());
489}
8d2b7645 490
532d6b3a
TJ
491BOOST_AUTO_TEST_CASE(FormatFullTime)
492{
8dce1f31 493 this->set_tz ("CET");
532d6b3a
TJ
494 time_t seconds = 1318844005;
495
496 BOOST_CHECK_EQUAL("17.10.2011 11:33", format_full_time(seconds));
497}
498
dad9e26f
GE
499BOOST_AUTO_TEST_CASE(DateToSeconds1)
500{
8dce1f31 501 this->set_tz ("CET");
dad9e26f
GE
502 // no DST
503 BOOST_CHECK_EQUAL(1325372400, date_to_seconds("2012-01-01"));
504}
505
506BOOST_AUTO_TEST_CASE(DateToSeconds2)
507{
8dce1f31 508 this->set_tz ("CET");
dad9e26f
GE
509 // DST
510 BOOST_CHECK_EQUAL(1341093600, date_to_seconds("2012-07-01"));
511}
512
d70f7269
PG
513BOOST_AUTO_TEST_CASE(FormatISO8601_T)
514{
515 const time_t moment = 1515492684;
516 BOOST_CHECK_EQUAL("10:11:24",
517 format_iso8601 (moment, true, false, true, false));
518}
519
520BOOST_AUTO_TEST_CASE(FormatISO8601_TZ_local)
521{
8dce1f31 522 this->set_tz ("CET");
d70f7269 523 const time_t moment = 1515492684;
a71d41c6 524 BOOST_CHECK_EQUAL("11:11:24+0100",
d70f7269
PG
525 format_iso8601 (moment, false, false, true, true));
526}
527
528BOOST_AUTO_TEST_CASE(FormatISO8601_TZ)
529{
530 const time_t moment = 1515492684;
a71d41c6 531 BOOST_CHECK_EQUAL("10:11:24+0000",
d70f7269
PG
532 format_iso8601 (moment, true, false, true, true));
533}
534
535BOOST_AUTO_TEST_CASE(FormatISO8601_DTZ_local)
536{
8dce1f31 537 this->set_tz ("CET");
d70f7269 538 const time_t moment = 1515492684;
a71d41c6 539 BOOST_CHECK_EQUAL("2018-01-09T11:11:24+0100",
d70f7269
PG
540 format_iso8601 (moment, false, true, true, true));
541}
542
543BOOST_AUTO_TEST_CASE(FormatISO8601_DTZ)
544{
545 const time_t moment = 1515492684;
a71d41c6 546 BOOST_CHECK_EQUAL("2018-01-09T10:11:24+0000",
d70f7269
PG
547 format_iso8601 (moment, true, true, true, true));
548}
549
550BOOST_AUTO_TEST_CASE(FormatISO8601_DT)
551{
552 const time_t moment = 1515492684;
553 BOOST_CHECK_EQUAL("2018-01-09T10:11:24",
554 format_iso8601 (moment, true, true, true, false));
555}
556
557BOOST_AUTO_TEST_CASE(FormatISO8601_D)
558{
559 const time_t moment = 1515492684;
560 BOOST_CHECK_EQUAL("2018-01-09",
561 format_iso8601 (moment, true, true, false, false));
562}
563
564BOOST_AUTO_TEST_CASE(FormatISO8601_DTZ_struct_tm)
565{
566 struct tm helau;
567 helau.tm_sec = 11;
568 helau.tm_min = 11;
569 helau.tm_hour = 11;
570 helau.tm_mday = 11;
571 helau.tm_mon = 10;
572 helau.tm_year = 2018 - 1900;
573 helau.tm_wday = 0;
574 helau.tm_yday = 315;
575 helau.tm_isdst = 0;
576 helau.tm_gmtoff = 0;
577 helau.tm_zone = NULL;
578
a71d41c6 579 BOOST_CHECK_EQUAL("2018-11-11T11:11:11+0000",
d70f7269
PG
580 format_iso8601 (helau, true, true, true));
581}
582
583BOOST_AUTO_TEST_CASE(FormatISO8601_DTZ_struct_timespec)
584{
585 struct timespec ts = { 1541934671, 11 };
586
a71d41c6 587 BOOST_CHECK_EQUAL("2018-11-11T11:11:11+0000",
d70f7269
PG
588 format_iso8601 (ts, true, true, true, true));
589}
590
8b5814e2
PG
591BOOST_AUTO_TEST_SUITE(Clock)
592
593 BOOST_AUTO_TEST_CASE(ctor_simple)
594 {
595 I2n::clock::Time t;
596
597 BOOST_CHECK_EQUAL(t.get_sec (), 0);
598 BOOST_CHECK_EQUAL(t.get_nsec (), 0);
599 }
600
601 BOOST_AUTO_TEST_CASE(ctor_type)
602 {
db783a1f
PG
603 I2n::clock::Time t1 (I2n::clock::type::real);
604 I2n::clock::Time t2 (I2n::clock::type::mono);
605 I2n::clock::Time t3 (I2n::clock::type::boot);
606 I2n::clock::Time t4 (I2n::clock::type::cpu);
8b5814e2 607
db783a1f
PG
608 BOOST_CHECK_EQUAL(t1.get_sec (), 0);
609 BOOST_CHECK_EQUAL(t1.get_nsec (), 0);
610
611 BOOST_CHECK_EQUAL(t2.get_sec (), 0);
612 BOOST_CHECK_EQUAL(t2.get_nsec (), 0);
613
614 BOOST_CHECK_EQUAL(t3.get_sec (), 0);
615 BOOST_CHECK_EQUAL(t3.get_nsec (), 0);
616
617 BOOST_CHECK_EQUAL(t4.get_sec (), 0);
618 BOOST_CHECK_EQUAL(t4.get_nsec (), 0);
8b5814e2
PG
619 }
620
621 BOOST_AUTO_TEST_CASE(ctor_variant)
622 {
db783a1f
PG
623 I2n::clock::Time tmc (I2n::clock::type::mono);
624 I2n::clock::Time tmr (I2n::clock::type::mono, I2n::clock::type::raw);
625 I2n::clock::Time tme (I2n::clock::type::mono, I2n::clock::type::exact);
8b5814e2 626
db783a1f
PG
627 I2n::clock::Time trc (I2n::clock::type::real);
628 I2n::clock::Time tre (I2n::clock::type::real, I2n::clock::type::exact);
629
630 I2n::clock::Time tb (I2n::clock::type::boot);
631
632 I2n::clock::Time tcp (I2n::clock::type::cpu);
633 I2n::clock::Time tct (I2n::clock::type::cpu, I2n::clock::type::thread);
634
635 BOOST_CHECK_EQUAL(tmc.get_sec (), 0); /* MONO */
636 BOOST_CHECK_EQUAL(tmc.get_nsec (), 0);
637
638 BOOST_CHECK_EQUAL(tmr.get_sec (), 0);
639 BOOST_CHECK_EQUAL(tmr.get_nsec (), 0);
640
641 BOOST_CHECK_EQUAL(tme.get_sec (), 0);
642 BOOST_CHECK_EQUAL(tme.get_nsec (), 0);
643
644 BOOST_CHECK_EQUAL(trc.get_sec (), 0); /* REAL */
645 BOOST_CHECK_EQUAL(trc.get_nsec (), 0);
646
647 BOOST_CHECK_EQUAL(tre.get_sec (), 0);
648 BOOST_CHECK_EQUAL(tre.get_nsec (), 0);
649
650 BOOST_CHECK_EQUAL(tb.get_sec (), 0); /* BOOT */
651 BOOST_CHECK_EQUAL(tb.get_nsec (), 0);
652
653 BOOST_CHECK_EQUAL(tcp.get_sec (), 0); /* CPU */
654 BOOST_CHECK_EQUAL(tcp.get_nsec (), 0);
655
656 BOOST_CHECK_EQUAL(tct.get_sec (), 0);
657 BOOST_CHECK_EQUAL(tct.get_nsec (), 0);
8b5814e2
PG
658 }
659
660 BOOST_AUTO_TEST_CASE(initializer_now)
661 {
662 boost::optional<I2n::clock::Time> t = I2n::clock::now ();
663
664 BOOST_CHECK(t);
665 BOOST_CHECK_GT(t->get_sec (), 0);
666 BOOST_CHECK_EQUAL(t->err, 0);
667 }
668
e36ca33c
PG
669 BOOST_AUTO_TEST_CASE(initializer_zero)
670 {
671 I2n::clock::Time stundenull = I2n::clock::zero ();
672
673 BOOST_CHECK_EQUAL(stundenull.get_sec (), 0);
674 BOOST_CHECK_EQUAL(stundenull.get_nsec (), 0);
675 BOOST_CHECK_EQUAL(stundenull.err, 0);
676 }
677
678 BOOST_AUTO_TEST_CASE(member_set_now)
679 {
680 I2n::clock::Time t;
681
682 BOOST_CHECK(t.set ());
683
684 BOOST_CHECK_NE(t.get_sec (), 0);
685 }
686
687 BOOST_AUTO_TEST_CASE(member_set_value)
688 {
689 I2n::clock::Time t;
690
691 t.set (42, 42);
692
693 BOOST_CHECK_EQUAL(t.get_sec (), 42);
694 BOOST_CHECK_EQUAL(t.get_nsec (), 42);
695 }
696
697 BOOST_AUTO_TEST_CASE(member_set_value_type)
698 {
699 I2n::clock::Time t;
700
701 t.set (42, 42, I2n::clock::type::real, I2n::clock::type::exact);
702
703 BOOST_CHECK_EQUAL(t.get_sec (), 42);
704 BOOST_CHECK_EQUAL(t.get_nsec (), 42);
705 }
706
707 BOOST_AUTO_TEST_CASE(member_add_parts)
708 {
709 I2n::clock::Time t;
710
711 t.set (42, 42);
712 t.add (2187, 2187);
713
714 BOOST_CHECK_EQUAL(t.get_sec (), 2229);
715 BOOST_CHECK_EQUAL(t.get_nsec (), 2229);
716 }
717
718 BOOST_AUTO_TEST_CASE(member_sub_parts)
719 {
720 I2n::clock::Time t;
721
722 t.set (2, 0L);
723 t.subtract (1, 1L);
724
725 BOOST_CHECK_EQUAL(t.get_sec (), 0);
726 BOOST_CHECK_EQUAL(t.get_nsec (), 999999999);
727 }
728
729 BOOST_AUTO_TEST_CASE(member_sub_Time)
730 {
731 I2n::clock::Time t1;
732 I2n::clock::Time t2;
733
734 t1.set (42, 42L);
735 t2.set (42, 0L);
736
737 t1.subtract (t2);
738
739 BOOST_CHECK_EQUAL(t1.get_sec (), 0);
740 BOOST_CHECK_EQUAL(t1.get_nsec (), 42L);
741 }
742
743 BOOST_AUTO_TEST_CASE(member_diff)
744 {
745 static const time_t five = 5 * 365 * 24 * 3600;
746
747 I2n::clock::Time t1 (42, 1337);
748 I2n::clock::Time t2 = t1 + five;;
749 I2n::clock::Time t3 = t1 - five;;
750
751 BOOST_CHECK_EQUAL(t2, I2n::clock::Time ((time_t)42 + five, 1337));
752 BOOST_CHECK_EQUAL(t3, I2n::clock::Time ((time_t)42 - five, 1337));
753 BOOST_CHECK_EQUAL(t1.difference (t3), t3.difference (t1));
754 BOOST_CHECK_EQUAL(t3.difference (t3), t3.difference (t3));
755 }
756
757 BOOST_AUTO_TEST_CASE(op_copyassign)
758 {
759 I2n::clock::Time t1;
760 I2n::clock::Time t2;
761
762 BOOST_CHECK(t1.set ());
763
764 t2 = t1;
765
766 BOOST_CHECK_EQUAL(t1.get_sec (), t2.get_sec ());
767 BOOST_CHECK_EQUAL(t1.get_nsec (), t2.get_nsec ());
768 }
769
770 BOOST_AUTO_TEST_CASE(op_equal)
771 {
772 I2n::clock::Time t1;
773 I2n::clock::Time t2;
774
775 BOOST_CHECK(t1.set ());
776 t2 = t1;
777
778 BOOST_CHECK_EQUAL(t1, t2);
779 }
780
781 BOOST_AUTO_TEST_CASE(op_add_Time)
782 {
783 I2n::clock::Time t1;
784 I2n::clock::Time t2;
785 I2n::clock::Time tsum;
786
787 t1.set (2187, 2187);
788 t2.set (1337, 1337);
789 tsum = t1 + t2;
790
791 BOOST_CHECK_EQUAL(tsum.get_sec (), 3524);
792 BOOST_CHECK_EQUAL(tsum.get_nsec (), 3524);
793 }
794
795 BOOST_AUTO_TEST_CASE(op_add_Time_carry)
796 {
797 I2n::clock::Time t1;
798 I2n::clock::Time t2;
799 I2n::clock::Time tsum;
800
801 t1.set (2187, 2187);
cf960f73
PG
802# if LONG_BIT == 32
803 t2.set (1300, 2L * 1000 * 1000 * 1000 + 1337);
804# else
e36ca33c 805 t2.set (1300, 37L * 1000 * 1000 * 1000 + 1337);
cf960f73 806# endif
e36ca33c
PG
807
808 tsum = t1 + t2;
809
cf960f73
PG
810# if LONG_BIT == 32
811 BOOST_CHECK_EQUAL(tsum.get_sec (), 3489);
812 BOOST_CHECK_EQUAL(tsum.get_nsec (), 3524);
813# else
e36ca33c
PG
814 BOOST_CHECK_EQUAL(tsum.get_sec (), 3524);
815 BOOST_CHECK_EQUAL(tsum.get_nsec (), 3524);
cf960f73 816# endif
e36ca33c
PG
817 }
818
819 BOOST_AUTO_TEST_CASE(op_add_time_t)
820 {
821 I2n::clock::Time t1 (2187, 2187);
822 time_t t2 = 1337;
823 I2n::clock::Time tsum;
824
825 tsum = t1 + t2;
826
827 BOOST_CHECK_EQUAL(tsum.get_sec (), 3524);
828 BOOST_CHECK_EQUAL(tsum.get_nsec (), 2187);
829 }
830
831 BOOST_AUTO_TEST_CASE(op_add_time_t_external)
832 {
833 time_t t1 = 1337;
834 I2n::clock::Time t2 (2187, 2187);
835 I2n::clock::Time tsum;
836
837 tsum = t1 + t2;
838
839 BOOST_CHECK_EQUAL(tsum.get_sec (), 3524);
840 BOOST_CHECK_EQUAL(tsum.get_nsec (), 2187);
841 }
842
843 BOOST_AUTO_TEST_CASE(op_incr_Time)
844 {
845 I2n::clock::Time t1 (2187, 2187);
846 I2n::clock::Time t2 (1337, 1337);
847
848 t1 += t2;
849
850 BOOST_CHECK_EQUAL(t1.get_sec (), 3524);
851 BOOST_CHECK_EQUAL(t1.get_nsec (), 3524);
852 }
853
854 BOOST_AUTO_TEST_CASE(op_incr_time_t)
855 {
856 I2n::clock::Time t1 (2187, 2187);
857 time_t t2 = 1337;
858
859 t1 += t2;
860
861 BOOST_CHECK_EQUAL(t1.get_sec (), 3524);
862 BOOST_CHECK_EQUAL(t1.get_nsec (), 2187);
863 }
864
865 BOOST_AUTO_TEST_CASE(op_subtract_Time)
866 {
867 I2n::clock::Time t1;
868 I2n::clock::Time t2;
869 I2n::clock::Time tdiff;
870
871 t1.set (2187, 2187);
872 t2.set (1337, 1337);
873 tdiff = t1 - t2;
874
875 BOOST_CHECK_EQUAL(tdiff.get_sec (), 850);
876 BOOST_CHECK_EQUAL(tdiff.get_nsec (), 850);
877 }
878
879 BOOST_AUTO_TEST_CASE(op_subtract_time_t)
880 {
881 I2n::clock::Time t1 (2187, 2187);
882 time_t t2 = 1337;
883 I2n::clock::Time tdiff;
884
885 tdiff = t1 - t2;
886
887 BOOST_CHECK_EQUAL(tdiff.get_sec (), 850);
888 BOOST_CHECK_EQUAL(tdiff.get_nsec (), 2187);
889 }
890
891 BOOST_AUTO_TEST_CASE(op_subtract_time_t_external)
892 {
893 time_t t1 = 1337;
894 I2n::clock::Time t2 (2187, 2187);
895 I2n::clock::Time tdiff;
896
897 tdiff = t1 - t2;
898
899 BOOST_CHECK_EQUAL(tdiff.get_sec (), -851);
900 BOOST_CHECK_EQUAL(tdiff.get_nsec (), 999997813);
901 }
902
903 BOOST_AUTO_TEST_CASE(op_decr_Time)
904 {
905 I2n::clock::Time t1 (2187, 2187);
906 I2n::clock::Time t2 (1337, 1337);
907
908 t1 -= t2;
909
910 BOOST_CHECK_EQUAL(t1.get_sec (), 850);
911 BOOST_CHECK_EQUAL(t1.get_nsec (), 850);
912 }
913
914 BOOST_AUTO_TEST_CASE(op_decr_time_t)
915 {
916 I2n::clock::Time t1 (2187, 2187);
917 time_t t2 = 1337;
918
919 t1 -= t2;
920
921 BOOST_CHECK_EQUAL(t1.get_sec (), 850);
922 BOOST_CHECK_EQUAL(t1.get_nsec (), 2187);
923 }
924
925 BOOST_AUTO_TEST_CASE(op_mult_scale)
926 {
927 I2n::clock::Time t1;
928 I2n::clock::Time t2;
929
930 t1.set (1, 1);
931 t2 = t1 * 42;
932
933 BOOST_CHECK_EQUAL(t2.get_sec (), 42);
934 BOOST_CHECK_EQUAL(t2.get_nsec (), 42);
935 }
936
937 BOOST_AUTO_TEST_CASE(op_mult_mutate)
938 {
939 I2n::clock::Time t1 ( 42, 42);
940 I2n::clock::Time t2 (1337, 0);
941
942 t1 *= 2;
943 t2 *= -10;
944
945 BOOST_CHECK_EQUAL(t1.get_sec (), 84);
946 BOOST_CHECK_EQUAL(t1.get_nsec (), 84);
947 BOOST_CHECK_EQUAL(t2.get_sec (), -13370);
948 }
949
950 BOOST_AUTO_TEST_CASE(op_mult_scale_carry)
951 {
952 I2n::clock::Time t1;
953 I2n::clock::Time t2;
954
955 t1.set (1, 500 * 1000 * 1000);
956 t2 = t1 * 3;
957
958 BOOST_CHECK_EQUAL(t2.get_sec (), 4);
959 BOOST_CHECK_EQUAL(t2.get_nsec (), 500 * 1000 * 1000);
960 }
961
962 BOOST_AUTO_TEST_CASE(op_equals)
963 {
964 I2n::clock::Time t1;
965 I2n::clock::Time t2;
966
967 t1.set (50, 50);
968 t2.set (50, 50);
969
970 BOOST_CHECK_EQUAL(t1, t2);
971 }
972
973 BOOST_AUTO_TEST_CASE(compare_equal)
974 {
975 I2n::clock::Time t1;
976 I2n::clock::Time t2;
977
978 t1.set (42, 42);
979 t2.set (42, 42);
980
981 BOOST_CHECK_EQUAL(I2n::clock::compare (t1, t2), 0);
982 }
983
984 BOOST_AUTO_TEST_CASE(compare_equal_type)
985 {
986 I2n::clock::Time t1 (42, 42, I2n::clock::type::real);
987 I2n::clock::Time t2 (42, 42, I2n::clock::type::cpu);
988 I2n::clock::Time t3 (42, 0, I2n::clock::type::real);
989 I2n::clock::Time t4 (42, 42, I2n::clock::type::real);
990
991 BOOST_CHECK_NE(t1, t2);
992 BOOST_CHECK_NE(t1, t3);
993 BOOST_CHECK_EQUAL(t1, t4);
994 }
995
996 BOOST_AUTO_TEST_CASE(compare_ne_sec)
997 {
998 I2n::clock::Time t1;
999 I2n::clock::Time t2;
1000
1001 t1.set ( 42, 42);
1002 t2.set (1337, 42);
1003
1004 BOOST_CHECK_EQUAL(I2n::clock::compare (t1, t2), -1);
1005 BOOST_CHECK_EQUAL(I2n::clock::compare (t2, t1), 1);
1006 }
1007
1008 BOOST_AUTO_TEST_CASE(compare_ne_nsec)
1009 {
1010 I2n::clock::Time t1;
1011 I2n::clock::Time t2;
1012
1013 t1.set (42, 42);
1014 t2.set (42, 1337);
1015
1016 BOOST_CHECK_EQUAL(I2n::clock::compare (t1, t2), -1);
1017 BOOST_CHECK_EQUAL(I2n::clock::compare (t2, t1), 1);
1018 }
1019
1020 BOOST_AUTO_TEST_CASE(compare_ne_both)
1021 {
1022 I2n::clock::Time t1;
1023 I2n::clock::Time t2;
1024
1025 t1.set (42, 2187);
1026 t2.set (23, 1337);
1027
1028 BOOST_CHECK_EQUAL(I2n::clock::compare (t1, t2), 1);
1029 BOOST_CHECK_EQUAL(I2n::clock::compare (t2, t1), -1);
1030 }
1031
1032 BOOST_AUTO_TEST_CASE(op_ineq_sec)
1033 {
1034 I2n::clock::Time t1 (1337);
1035 I2n::clock::Time t2 (2187);
1036
1037 BOOST_CHECK_LT(t1, t2);
1038 BOOST_CHECK_GT(t2, t1);
1039 }
1040
1041 BOOST_AUTO_TEST_CASE(op_ineq_nsec)
1042 {
1043 I2n::clock::Time t1 (1337, 23);
1044 I2n::clock::Time t2 (1337, 42);
1045
1046 BOOST_CHECK_LT(t1, t2);
1047 BOOST_CHECK_GT(t2, t1);
1048 }
1049
1050 BOOST_AUTO_TEST_CASE(op_ineq_both)
1051 {
1052 I2n::clock::Time t1 (2187, 23);
1053 I2n::clock::Time t2 (1337, 42);
1054
1055 BOOST_CHECK_LT(t2, t1);
1056 BOOST_CHECK_GT(t1, t2);
1057 }
1058
1059 BOOST_AUTO_TEST_CASE(op_eq_time_t)
1060 {
1061 boost::optional<I2n::clock::Time> t1 = I2n::clock::now ();
1062 const time_t t2 = time (NULL); /* race here */
1063
1064 *t1 -= (time_t)42;
1065
1066 BOOST_CHECK_NE(*t1, t2);
1067 BOOST_CHECK_LT(*t1, t2);
1068 BOOST_CHECK_GT( t2, *t1);
1069 }
1070
9f39641d
PG
1071 BOOST_AUTO_TEST_CASE(Format_sec_msec)
1072 {
1073 I2n::clock::Time t1 (42, 42);
1074 I2n::clock::Time t2 ( 4, 242424242);
1075 I2n::clock::Time t3 ( 0, 133713371);
1076 I2n::clock::Time t4 ( 0, 0);
1077
1078 std::string s1 = t1.format_sec_msec ();
1079 std::string s2 = t2.format_sec_msec ();
1080 std::string s3 = t3.format_sec_msec ();
1081 std::string s4 = t4.format_sec_msec ();
1082
1083 BOOST_CHECK_EQUAL("42s 0ms" , s1);
1084 BOOST_CHECK_EQUAL( "4s 242ms", s2);
1085 BOOST_CHECK_EQUAL( "0s 133ms", s3);
1086 BOOST_CHECK_EQUAL( "0s 0ms" , s4);
1087 }
1088
1089 BOOST_AUTO_TEST_CASE(Format_min_sec_msec)
1090 {
1091 I2n::clock::Time t1 (42*60 + 42, 42);
1092 I2n::clock::Time t2 ( 4*60 + 42, 242424242);
1093 I2n::clock::Time t3 ( 0*60 + 42, 133713371);
1094 I2n::clock::Time t4 ( 0 + 0, 0);
1095
1096 std::string s1 = *t1.format_min_sec_msec ();
1097 std::string s2 = *t2.format_min_sec_msec ();
1098 std::string s3 = *t3.format_min_sec_msec ();
1099 std::string s4 = *t4.format_min_sec_msec ();
1100
1101 BOOST_CHECK_EQUAL("42m42.000s", s1);
1102 BOOST_CHECK_EQUAL( "4m42.242s", s2);
1103 BOOST_CHECK_EQUAL( "0m42.133s", s3);
1104 BOOST_CHECK_EQUAL( "0m0.000s", s4);
1105 }
1106
72acd54c
PG
1107 BOOST_AUTO_TEST_CASE(FormatISO8601_T)
1108 {
1109 I2n::clock::Time t (42, 42);
1110 boost::optional<std::string> s = t.format_iso8601 (true, false, true, false);
1111
1112 BOOST_CHECK_EQUAL("00:00:42", *s);
1113 }
1114
1115 BOOST_AUTO_TEST_CASE(FormatISO8601_DT)
1116 {
1117 I2n::clock::Time t (1541934671, 0);
1118 boost::optional<std::string> s = t.format_iso8601 (true, true, true, false);
1119
1120 BOOST_CHECK_EQUAL("2018-11-11T11:11:11", *s);
1121 }
1122
1123 BOOST_AUTO_TEST_CASE(FormatISO8601_DTZ)
1124 {
1125 I2n::clock::Time t (1541934671, 0);
1126 boost::optional<std::string> s = t.format_iso8601 (true, true, true, true);
1127
a71d41c6 1128 BOOST_CHECK_EQUAL("2018-11-11T11:11:11+0000", *s);
72acd54c
PG
1129 }
1130
1131 BOOST_AUTO_TEST_CASE(Format_make_nice_time)
1132 {
1133 I2n::clock::Time t (111111, 0);
1134 boost::optional<std::string> s = t.make_nice_time ();
1135
1136 BOOST_CHECK_EQUAL("1 day, 06:51:51", *s);
1137 }
1138
1139 BOOST_AUTO_TEST_CASE(Format_format_full_time)
1140 {
1141 I2n::clock::Time t (1541934671, 0);
1142 /*
1143 * brr, the old formatters use localtime without a way to opt out of
1144 * it!
1145 */
ccbeb66c 1146 this->set_utc ();
72acd54c
PG
1147 boost::optional<std::string> s = t.format_full_time ();
1148
1149 BOOST_CHECK_EQUAL("11.11.2018 11:11", *s);
1150 }
1151
1152 BOOST_AUTO_TEST_CASE(Format_format_date)
1153 {
1154 I2n::clock::Time t (1541934671, 0);
1155 boost::optional<std::string> s = t.format_date ();
1156
1157 BOOST_CHECK_EQUAL("11.11.2018", *s);
1158 }
1159
2795e39c
PG
1160 BOOST_AUTO_TEST_CASE(FromString_iso8601_full)
1161 {
a71d41c6
PG
1162 const std::string in1 ("0001-01-01T00:00:00+0000");
1163 const std::string in2 ("2018-11-11T11:11:11+0000");
2795e39c 1164
ccbeb66c
PG
1165 this->set_utc ();
1166
2795e39c
PG
1167 boost::optional<I2n::clock::Time> t1 = I2n::clock::time_of_iso8601 (in1);
1168 boost::optional<I2n::clock::Time> t2 = I2n::clock::time_of_iso8601 (in2);
1169
cf960f73
PG
1170# if LONG_BIT == 32
1171 BOOST_CHECK(!t1);
1172# else
2795e39c 1173 BOOST_CHECK(t1);
2795e39c 1174 BOOST_CHECK_EQUAL(*t1->format_iso8601 (), in1);
cf960f73
PG
1175# endif
1176
1177 BOOST_CHECK(t2);
2795e39c
PG
1178 BOOST_CHECK_EQUAL(*t2->format_iso8601 (), in2);
1179 }
1180
1181 BOOST_AUTO_TEST_CASE(FromString_iso8601_full_negyear)
1182 {
a71d41c6
PG
1183 const std::string in1 ("-0001-01-01T00:00:00+0000");
1184 const std::string in2 ("-2018-11-11T11:11:11+0000");
2795e39c 1185
ccbeb66c
PG
1186 this->set_utc ();
1187
2795e39c
PG
1188 boost::optional<I2n::clock::Time> t1 = I2n::clock::time_of_iso8601 (in1);
1189 boost::optional<I2n::clock::Time> t2 = I2n::clock::time_of_iso8601 (in2);
1190
cf960f73
PG
1191# if LONG_BIT == 32
1192 BOOST_CHECK(!t1);
1193 BOOST_CHECK(!t2);
1194# else
2795e39c
PG
1195 BOOST_CHECK(t1);
1196 BOOST_CHECK(t2);
2795e39c
PG
1197 BOOST_CHECK_EQUAL(*t1->format_iso8601 (), in1);
1198 BOOST_CHECK_EQUAL(*t2->format_iso8601 (), in2);
cf960f73 1199# endif
2795e39c
PG
1200 }
1201
78e6a1b2 1202# ifndef GLIBC_STRPTIME_LACKS_Z
a71d41c6
PG
1203 BOOST_AUTO_TEST_CASE(FromString_iso8601_Z)
1204 {
1205 const std::string in1 ("2019-04-25T13:41:47+0000");
1206 const std::string in2 ("2019-04-25T13:41:47Z");
1207
1208 this->set_utc ();
1209 boost::optional<I2n::clock::Time> t1 = I2n::clock::time_of_iso8601 (in1, true, true, true);
1210 boost::optional<I2n::clock::Time> t2 = I2n::clock::time_of_iso8601 (in2, true, true, true);
1211
1212 BOOST_CHECK(t1);
1213 BOOST_CHECK(t2);
1214
1215 BOOST_CHECK_EQUAL(*t1, *t2);
1216 BOOST_CHECK_EQUAL(*t1->format_iso8601 (), *t2->format_iso8601 ());
1217 BOOST_CHECK_EQUAL(*t2->format_iso8601 (), in1);
1218 }
78e6a1b2 1219# endif
a71d41c6 1220
2795e39c
PG
1221 BOOST_AUTO_TEST_CASE(FromString_iso8601_partial)
1222 {
1223 const std::string in1 ("2018-11-11T11:11:11");
1224 const std::string in2 ("2018-11-11");
cf960f73 1225
ccbeb66c 1226 this->set_utc ();
2795e39c
PG
1227
1228 boost::optional<I2n::clock::Time> t1 =
1229 I2n::clock::time_of_iso8601 (in1, true, true, false);
1230 boost::optional<I2n::clock::Time> t2 =
1231 I2n::clock::time_of_iso8601 (in2, true, false, false);
2795e39c
PG
1232
1233 BOOST_CHECK(t1);
1234 BOOST_CHECK(t2);
2795e39c
PG
1235 /*
1236 * We test for the difference here which is zero if the number is
1237 * correct but causes the difference from the expected value to be
1238 * printed in case the test fails.
1239 */
1240 BOOST_CHECK_EQUAL(*t1->format_iso8601 (true, true, true, false), in1);
1241 BOOST_CHECK_EQUAL(*t2->format_iso8601 (true, true, false, false), in2);
cf960f73
PG
1242 }
1243
52554fd1
PG
1244 BOOST_AUTO_TEST_CASE(FromString_iso8601_offset)
1245 {
1246 const std::string in1 ("2019-04-25T13:41:47Z");
1247 const std::string in2 ("2019-04-25T13:41:47+0200"); /* = UTC(in1 + 2h) */
1248 const std::string in3 ("2019-04-25T15:41:47+0000"); /* = UTC(in2) */
1249
1250 this->set_utc ();
1251 boost::optional<I2n::clock::Time> t1 = I2n::clock::time_of_iso8601 (in1, true, true, true);
1252 boost::optional<I2n::clock::Time> t2 = I2n::clock::time_of_iso8601 (in2, true, true, true);
1253 boost::optional<I2n::clock::Time> t3 = I2n::clock::time_of_iso8601 (in3, true, true, true);
1254
78e6a1b2
PG
1255# ifdef GLIBC_STRPTIME_LACKS_Z
1256 BOOST_CHECK(!t1);
1257# else
52554fd1 1258 BOOST_CHECK(t1);
78e6a1b2 1259# endif
52554fd1
PG
1260 BOOST_CHECK(t2);
1261 BOOST_CHECK(t3);
1262
78e6a1b2 1263# ifndef GLIBC_STRPTIME_LACKS_Z
52554fd1
PG
1264 BOOST_CHECK_EQUAL(*t1->format_iso8601 (), "2019-04-25T13:41:47+0000");
1265 BOOST_CHECK_EQUAL(t1->get_sec (), 1556199707);
78e6a1b2 1266# endif
52554fd1 1267 BOOST_CHECK_EQUAL(*t2->format_iso8601 (), "2019-04-25T15:41:47+0000");
78e6a1b2 1268# ifndef GLIBC_STRPTIME_LACKS_Z
52554fd1 1269 BOOST_CHECK_EQUAL(t2->get_sec (), t1->get_sec () + 2 * 60 * 60);
78e6a1b2 1270# endif
52554fd1
PG
1271 BOOST_CHECK_EQUAL(*t2, *t3);
1272 BOOST_CHECK_EQUAL(*t3->format_iso8601 (), "2019-04-25T15:41:47+0000");
1273 }
1274
1275 BOOST_AUTO_TEST_CASE(FromString_iso8601_tzdiff)
1276 {
1277 const std::string in ("2019-04-26T13:45:02+0000");
1278
1279 this->set_tz ("UTC");
1280 boost::optional<I2n::clock::Time> t1 = I2n::clock::time_of_iso8601 (in, true, true, false);
1281
1282 this->set_tz ("CET");
1283 boost::optional<I2n::clock::Time> t2 = I2n::clock::time_of_iso8601 (in, true, true, false);
1284
1285 BOOST_CHECK_EQUAL(*t1->format_iso8601 (true, true, true, true), in);
1286 BOOST_CHECK_EQUAL(*t2->format_iso8601 (true, true, true, true), "2019-04-26T13:45:02+0000");
1287 }
1288
cf960f73
PG
1289 BOOST_AUTO_TEST_CASE(FromString_iso8601_32bit_time_t_err)
1290 {
1291 const std::string timeless ("11:11:11");
1292 boost::optional<I2n::clock::Time> untimely = boost::none;
1293
ccbeb66c
PG
1294 this->set_utc ();
1295
cf960f73
PG
1296 untimely = I2n::clock::time_of_iso8601 (timeless, false, true, false);
1297
1298# if LONG_BIT == 32
1299 BOOST_CHECK(!untimely);
1300# else
1301 BOOST_CHECK(untimely);
1302 BOOST_CHECK_EQUAL(*untimely->format_iso8601 (true, false, true, false),
1303 timeless);
1304# endif
1305 }
1306
1307 BOOST_AUTO_TEST_CASE(Ctor_32bit_time_t_err)
1308 {
1309 boost::optional<std::string> threw = boost::none;
1310
1311 struct tm tm;
1312 memset (&tm, 0, sizeof (tm));
1313
1314 tm.tm_sec = 11;
1315 tm.tm_min = 11;
1316 tm.tm_hour = 11;
1317 tm.tm_mday = 11;
1318 tm.tm_mon = 10;
1319 tm.tm_year = -789;
1320 tm.tm_gmtoff = 0;
1321
1322 try {
1323 I2n::clock::Time untimely (tm);
1324 } catch (I2n::clock::conversion_error &exn) {
1325 threw = std::string (exn);
1326 }
1327
1328
1329# if LONG_BIT == 32
1330 BOOST_CHECK_EQUAL(*threw,
1331 "errno=0 [mktime: from struct tm {Sun Nov 11 11:11:11 1111}]");
1332# else
1333 BOOST_CHECK(!threw);
1334# endif
2795e39c
PG
1335 }
1336
c42fd3b3
PG
1337 BOOST_AUTO_TEST_CASE(containers_list)
1338 {
1339 std::list<I2n::clock::Time> ts;
1340
1341 ts.push_back (I2n::clock::zero ());
1342 ts.push_back (I2n::clock::zero ());
1343
1344 BOOST_CHECK_EQUAL(ts.size (), 2);
1345 }
1346
1347 BOOST_AUTO_TEST_CASE(containers_vec)
1348 {
1349 std::vector<I2n::clock::Time> ts;
1350
1351 ts.push_back (I2n::clock::zero ());
1352 ts.push_back (I2n::clock::zero ());
1353
1354 BOOST_CHECK_EQUAL(ts.size (), 2);
1355 }
1356
1357 BOOST_AUTO_TEST_CASE(containers_set)
1358 {
1359 std::set<I2n::clock::Time> ts;
1360
1361 ts.insert (I2n::clock::zero ());
1362 ts.insert (I2n::clock::Time (42, 2187));
1363 ts.insert (I2n::clock::zero ());
1364
1365 BOOST_CHECK_EQUAL(ts.size (), 2);
1366 }
1367
1368 BOOST_AUTO_TEST_CASE(containers_list_mean)
1369 {
1370 std::list<I2n::clock::Time> ts;
1371
1372 ts.push_back (I2n::clock::Time (42, 42));
1373 ts.push_back (I2n::clock::Time (1337, 1337));
1374
1375 BOOST_CHECK_EQUAL(I2n::clock::mean (ts),
1376 I2n::clock::Time (689, 500000689));
1377 }
1378
1379 BOOST_AUTO_TEST_CASE(containers_list_mean_zero)
1380 {
1381 std::list<I2n::clock::Time> ts;
1382
1383 ts.push_back (I2n::clock::Time (0, 0));
1384 ts.push_back (I2n::clock::Time (0, 0));
1385 ts.push_back (I2n::clock::Time (0, 0));
1386 ts.push_back (I2n::clock::Time (0, 0));
1387
1388 BOOST_CHECK_EQUAL(I2n::clock::mean (ts),
1389 I2n::clock::zero ());
1390 }
1391
1392 BOOST_AUTO_TEST_CASE(containers_list_mean_empty)
1393 {
1394 std::list<I2n::clock::Time> ts;
1395
1396 BOOST_CHECK_EQUAL(I2n::clock::mean (ts), I2n::clock::Time (0, 0));
1397 }
1398
1399 BOOST_AUTO_TEST_CASE(containers_set_mean)
1400 {
1401 std::set<I2n::clock::Time> ts;
1402
1403 ts.insert (I2n::clock::Time (42));
1404 ts.insert (I2n::clock::Time (1337));
1405 ts.insert (I2n::clock::Time (2187));
1406
1407 BOOST_CHECK_EQUAL(I2n::clock::mean (ts),
1408 I2n::clock::Time (1188, 666666666));
1409 }
1410
1411 BOOST_AUTO_TEST_CASE(containers_set_median_empty)
1412 {
1413 std::set<I2n::clock::Time> ts;
1414
1415 BOOST_CHECK_EQUAL(I2n::clock::median (ts), I2n::clock::Time (0, 0));
1416 }
1417
1418 BOOST_AUTO_TEST_CASE(containers_set_median_one)
1419 {
1420 std::set<I2n::clock::Time> ts;
1421
1422 ts.insert (I2n::clock::Time (42, 0));
1423
1424 BOOST_CHECK_EQUAL(I2n::clock::median (ts),
1425 I2n::clock::Time (42, 0));
1426 }
1427
1428 BOOST_AUTO_TEST_CASE(containers_set_median_multi)
1429 {
1430 std::set<I2n::clock::Time> ts;
1431
1432 ts.insert (I2n::clock::Time (42));
1433 ts.insert (I2n::clock::Time (1337));
1434 ts.insert (I2n::clock::Time (2187));
1435
1436 BOOST_CHECK_EQUAL(I2n::clock::median (ts), I2n::clock::Time (1337));
1437 }
1438
1439 BOOST_AUTO_TEST_CASE(containers_vec_median_multi)
1440 {
1441 std::vector<I2n::clock::Time> ts;
1442
1443 ts.push_back (I2n::clock::Time (42));
1444 ts.push_back (I2n::clock::Time (1337));
1445 ts.push_back (I2n::clock::Time (2187));
1446
1447 BOOST_CHECK_EQUAL(I2n::clock::median (ts), I2n::clock::Time (1337));
1448 }
1449
1450 BOOST_AUTO_TEST_CASE(containers_list_median_multi)
1451 {
1452 std::list<I2n::clock::Time> ts;
1453
1454 ts.push_back (I2n::clock::Time (42));
1455 ts.push_back (I2n::clock::Time (1337));
1456 ts.push_back (I2n::clock::Time (2187));
cf960f73
PG
1457 ts.push_back (I2n::clock::Time (0xdead));
1458 ts.push_back (I2n::clock::Time (0xbeef));
c42fd3b3 1459
cf960f73
PG
1460 BOOST_CHECK_EQUAL(I2n::clock::median (ts),
1461 I2n::clock::Time (2187));
c42fd3b3
PG
1462 }
1463
1464 BOOST_AUTO_TEST_CASE(containers_list_median_multi_evensize)
1465 {
1466 std::list<I2n::clock::Time> ts;
1467
1468 ts.push_back (I2n::clock::Time (42));
1469 ts.push_back (I2n::clock::Time (1337));
1470 ts.push_back (I2n::clock::Time (2187));
1471 ts.push_back (I2n::clock::Time (0xf00d));
cf960f73
PG
1472 ts.push_back (I2n::clock::Time (0xfeed));
1473 ts.push_back (I2n::clock::Time (0xdeadf0e));
c42fd3b3
PG
1474
1475 BOOST_CHECK_EQUAL(I2n::clock::median (ts), I2n::clock::Time (0xf00d));
1476 }
1477
e36ca33c 1478BOOST_AUTO_TEST_SUITE_END() /* [Clock] */
dad9e26f 1479
9fe0853b 1480BOOST_AUTO_TEST_SUITE_END()