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