1 /* $Id: test_ncbitime.cpp 621326 2020-12-09 19:22:45Z ivanov $
2 * ===========================================================================
3 *
4 * PUBLIC DOMAIN NOTICE
5 * National Center for Biotechnology Information
6 *
7 * This software/database is a "United States Government Work" under the
8 * terms of the United States Copyright Act. It was written as part of
9 * the author's official duties as a United States Government employee and
10 * thus cannot be copyrighted. This software/database is freely available
11 * to the public for use. The National Library of Medicine and the U.S.
12 * Government have not placed any restriction on its use or reproduction.
13 *
14 * Although all reasonable efforts have been taken to ensure the accuracy
15 * and reliability of the software and data, the NLM and the U.S.
16 * Government do not and cannot warrant the performance or results that
17 * may be obtained by using this software or data. The NLM and the U.S.
18 * Government disclaim all warranties, express or implied, including
19 * warranties of performance, merchantability or fitness for any particular
20 * purpose.
21 *
22 * Please cite the author in any work or product based on this material.
23 *
24 * ===========================================================================
25 *
26 * Authors: Anton Butanayev, Denis Vakatov, Vladimir Ivanov
27 *
28 * File Description:
29 * Test for CTime - the standard Date/Time class.
30 *
31 * NOTE:
32 * The time change dates for Daylight Saving Time in the U.S. and
33 * Europe are different. Because this test have hardcoded dates, it works
34 * only on the machines with the same DST standards as in the U.S.
35 *
36 */
37
38 #include <ncbi_pch.hpp>
39 #include <corelib/ncbitime.hpp>
40 #include <corelib/ncbi_system.hpp>
41 #include <corelib/ncbisys.hpp>
42 #include <stdio.h>
43 #include <stdlib.h>
44
45 #include <common/test_assert.h> /* This header must go last */
46
47 USING_NCBI_SCOPE;
48
49
50 // Macro to enable/disable speed tests
51 #define ENABLE_SPEED_TESTS 0
52
53 // String printout
54 #define STR(t) string("[" + (t).AsString() + "]")
55
56 #if defined(NCBI_OS_DARWIN) || defined(NCBI_OS_BSD)
57 # define TIMEZONE_IS_UNDEFINED 1
58 #endif
59
60
61 //============================================================================
62 //
63 // TestMisc
64 //
65 //============================================================================
66
s_TestMisc(void)67 static void s_TestMisc(void)
68 {
69 // Get current time
70 {{
71 CTime t0(CTime::eCurrent);
72 CCurrentTime t1;
73 assert(CTimeSpan(t1-t0).GetAsDouble() <= 1);
74 }}
75
76 // Month and Day name<->num conversion
77 {{
78 assert(CTime::MonthNameToNum("Jan") == CTime::eJanuary);
79 assert(CTime::MonthNameToNum("January") == 1);
80 assert(CTime::MonthNameToNum("JAN") == CTime::eJanuary);
81 assert(CTime::MonthNameToNum("JANUARY") == 1);
82 assert(CTime::MonthNameToNum("Dec") == CTime::eDecember);
83 assert(CTime::MonthNameToNum("December") == 12);
84 assert(CTime::MonthNumToName(CTime::eJanuary) == "January");
85 assert(CTime::MonthNumToName(1, CTime::eAbbr) == "Jan");
86 assert(CTime::MonthNumToName(CTime::eDecember,
87 CTime::eFull) == "December");
88 assert(CTime::MonthNumToName(12,CTime::eAbbr) == "Dec");
89
90 assert(CTime::DayOfWeekNameToNum("Sun") == CTime::eSunday);
91 assert(CTime::DayOfWeekNameToNum("Sunday") == 0);
92 assert(CTime::DayOfWeekNameToNum("SUN") == CTime::eSunday);
93 assert(CTime::DayOfWeekNameToNum("SUNDAY") == 0);
94 assert(CTime::DayOfWeekNameToNum("Sat") == CTime::eSaturday);
95 assert(CTime::DayOfWeekNameToNum("Saturday") == 6);
96 assert(CTime::DayOfWeekNumToName(CTime::eSunday) == "Sunday");
97 assert(CTime::DayOfWeekNumToName(0,CTime::eAbbr) == "Sun");
98 assert(CTime::DayOfWeekNumToName(CTime::eSaturday,
99 CTime::eFull) == "Saturday");
100 assert(CTime::DayOfWeekNumToName(6,CTime::eAbbr) == "Sat");
101 try {
102 CTime::MonthNameToNum("Month");
103 _TROUBLE;
104 }
105 catch (CTimeException&) {}
106 }}
107
108 // String <-> CTime conversion
109 {{
110 {{
111 CTime t;
112 assert(t.AsString() == "");
113 }}
114 {{
115 CTime t(2000, 365 / 2);
116 CTime::SetFormat("M/D/Y h:m:s");
117 assert(t.AsString() == "06/30/2000 00:00:00");
118 }}
119 {{
120 // Year 2000 problem:
121 CTime::SetFormat("M/D/Y");
122 CTime t(1999, 12, 30);
123 t.AddDay();
124 assert(t.AsString() == "12/31/1999");
125 t.AddDay();
126 assert(t.AsString() == "01/01/2000");
127 t.AddDay();
128 assert(t.AsString() == "01/02/2000");
129 t="02/27/2000";
130 t.AddDay();
131 assert(t.AsString() == "02/28/2000");
132 t.AddDay();
133 assert(t.AsString() == "02/29/2000");
134 t.AddDay();
135 assert(t.AsString() == "03/01/2000");
136 t.AddDay();
137 assert(t.AsString() == "03/02/2000");
138 }}
139 {{
140 // String assignment:
141 CTime::SetFormat("M/D/Y h:m:s");
142 try {
143 CTime t("02/15/2000 01:12:33");
144 assert(t.AsString() == "02/15/2000 01:12:33");
145 t = "6/16/2001 02:13:34";
146 assert(t.AsString() == "06/16/2001 02:13:34");
147 }
148 catch (CTimeException&) {}
149 }}
150 }}
151
152 // Comparison
153 {{
154 CTime empty;
155 CTime cl(CTime::eCurrent, CTime::eLocal);
156 CTime cg(cl);
157 cg.ToGmtTime();
158
159 assert( !(empty > empty) );
160 assert( !(empty < empty) );
161 assert( (empty == empty) );
162 assert( !(empty > cl) );
163 assert( (empty < cl) );
164 assert( !(empty == cl) );
165 assert( !(empty > cg) );
166 assert( (empty < cg) );
167 assert( !(empty == cg) );
168 assert( (cl > empty) );
169 assert( !(cl < empty) );
170 assert( !(cl == empty) );
171 assert( (cg > empty) );
172 assert( !(cg < empty) );
173 assert( !(cg == empty) );
174 assert( !(cg > cl) );
175 assert( !(cg < cl) );
176 assert( (cg == cl) );
177 assert( !(cl > cg) );
178 assert( !(cl < cg) );
179 assert( (cl == cg) );
180 }}
181
182 // Addition
183 {{
184 CTime::SetFormat("M/D/Y h:m:s.S");
185 {{
186 // Adding Nanoseconds
187 CTime t;
188 for (CTime tmp(1999, 12, 31, 23, 59, 59, 999999995);
189 tmp <= CTime(2000, 1, 1, 0, 0, 0, 000000003);
190 t = tmp, tmp.AddNanoSecond(2)) {
191 }
192 assert(t.AsString() == "01/01/2000 00:00:00.000000003");
193 }}
194 {{
195 // Current time with nanoseconds (10 cycles)
196 CTime t;
197 for (int i = 0; i < 10; i++) {
198 t.SetCurrent();
199 }
200 }}
201
202 CTime::SetFormat("M/D/Y h:m:s");
203 {{
204 // nAdding seconds
205 CTime t;
206 for (CTime tmp(1999, 12, 31, 23, 59, 5);
207 tmp <= CTime(2000, 1, 1, 0, 1, 20);
208 t = tmp, tmp.AddSecond(11)) {
209 }
210 assert(t.AsString() == "01/01/2000 00:01:17");
211 }}
212 {{
213 // Adding minutes
214 for (CTime t(1999, 12, 31, 23, 45);
215 t <= CTime(2000, 1, 1, 0, 15);
216 t.AddMinute(11)) {
217 }
218 }}
219 {{
220 // Adding hours
221 for (CTime t(1999, 12, 31);
222 t <= CTime(2000, 1, 1, 15);
223 t.AddHour(11)) {
224 }
225 }}
226 {{
227 // Adding months
228 for (CTime t(1998, 12, 29);
229 t <= CTime(1999, 4, 1);
230 t.AddMonth()) {
231 }
232 }}
233 {{
234 // Adding time span
235 CTime t0(1999, 12, 31, 23, 59, 5);
236 CTimeSpan ts(1, 2, 3, 4, 555555555);
237
238 for (int i=0; i<10; i++) {
239 t0.AddTimeSpan(ts);
240 }
241 assert(t0.AsString() == "01/11/2000 20:29:50");
242
243 CTime t1;
244 t1 = t0 + ts;
245 assert(t0.AsString() == "01/11/2000 20:29:50");
246 assert(t1.AsString() == "01/12/2000 22:32:55");
247 t1 = ts + t0;
248 assert(t0.AsString() == "01/11/2000 20:29:50");
249 assert(t1.AsString() == "01/12/2000 22:32:55");
250 t1 = t0; t1 += ts;
251 assert(t0.AsString() == "01/11/2000 20:29:50");
252 assert(t1.AsString() == "01/12/2000 22:32:55");
253 t1 = t0 - ts;
254 assert(t0.AsString() == "01/11/2000 20:29:50");
255 assert(t1.AsString() == "01/10/2000 18:26:45");
256 t1 = t0; t1 -= ts;
257 assert(t0.AsString() == "01/11/2000 20:29:50");
258 assert(t1.AsString() == "01/10/2000 18:26:45");
259 ts = t0 - t1;
260 assert(ts.AsString() == "93784.555555555");
261 ts = t1 - t0;
262 assert(ts.AsString() == "-93784.555555555");
263 }}
264 }}
265
266 // Difference
267 {{
268 CTime t1(2000, 10, 1, 12, 3, 45,1);
269 CTime t2(2000, 10, 2, 14, 55, 1,2);
270 CTimeSpan ts(1,2,51,16,1);
271
272 assert((t2.DiffDay(t1) - 1.12) < 0.01);
273 assert((t2.DiffHour(t1) - 26.85) < 0.01);
274 assert((t2.DiffMinute(t1) - 1611.27) < 0.01);
275 assert( t2.DiffSecond(t1) == 96676);
276 assert( t1.DiffSecond(t2) == -96676);
277 assert(NStr::DoubleToString(t2.DiffNanoSecond(t1),0) == "96676000000001");
278 assert(t2.DiffTimeSpan(t1) == ts);
279 assert(t1.DiffTimeSpan(t2) == -ts);
280
281 t1 = t2; // both local times
282 t1.SetTimeZone(CTime::eUTC);
283 ts = CTimeSpan(long(t1.DiffSecond(t2)));
284 assert(ts.GetAsDouble() == double(t2.TimeZoneOffset()));
285 }}
286
287 // CXX-195
288 {{
289 CTime time1("12/31/2007 20:00", "M/D/Y h:m");
290 CTime time2("1/1/2008 20:00", "M/D/Y h:m");
291 CTime time3("12/31/2007", "M/D/Y");
292 CTime time4("1/1/2008", "M/D/Y");
293 ERR_POST(Note << "time1=" << time1.AsString("M/D/Y h:m:s")
294 << " time_t=" << time1.GetTimeT()
295 << " time-zone: " << time1.TimeZoneOffset());
296 ERR_POST(Note << "time2=" << time2.AsString("M/D/Y h:m:s")
297 << " time_t=" << time2.GetTimeT()
298 << " time-zone: " << time2.TimeZoneOffset());
299 assert(time1.TimeZoneOffset() == time2.TimeZoneOffset());
300 ERR_POST(Note << "time3=" << time3.AsString("M/D/Y h:m:s")
301 << " time_t=" << time3.GetTimeT()
302 << " time-zone: " << time3.TimeZoneOffset());
303 assert(time2.TimeZoneOffset() == time3.TimeZoneOffset());
304 ERR_POST(Note << "time4=" << time4.AsString("M/D/Y h:m:s")
305 << " time_t=" << time4.GetTimeT()
306 << " time-zone: " << time4.TimeZoneOffset());
307 assert(time3.TimeZoneOffset() == time4.TimeZoneOffset());
308 }}
309
310 // Database formats conversion
311 {{
312 CTime t1(2000, 1, 1, 1, 1, 1, 10000000);
313 CTime::SetFormat("M/D/Y h:m:s.S");
314
315 TDBTimeU dbu = t1.GetTimeDBU();
316 assert(dbu.days == 36524);
317 assert(dbu.time == 61);
318 TDBTimeI dbi = t1.GetTimeDBI();
319 assert(dbi.days == 36524);
320 assert(dbi.time == 1098303);
321
322 CTime t2;
323 t2.SetTimeDBU(dbu);
324 assert(t2.AsString() == "01/01/2000 01:01:00.000000000");
325 t2.SetTimeDBI(dbi);
326 assert(t2.AsString() == "01/01/2000 01:01:01.010000000");
327 CTime::SetFormat("M/D/Y h:m:s");
328 dbi.days = 37093;
329 dbi.time = 12301381;
330 t2.SetTimeDBI(dbi);
331 assert(t2.AsString() == "07/23/2001 11:23:24");
332 }}
333
334 // Set* functions
335 {{
336 CTime::SetFormat("M/D/Y h:m:s");
337 CTime t(2000, 1, 31);
338
339 t.SetMonth(2);
340 assert(t.AsString() == "02/29/2000 00:00:00");
341 t.SetYear(2001);
342 assert(t.AsString() == "02/28/2001 00:00:00");
343 t.SetMonth(4);
344 assert(t.AsString() == "04/28/2001 00:00:00");
345 t.SetDay(31);
346 assert(t.AsString() == "04/30/2001 00:00:00");
347 t.SetHour(6);
348 assert(t.AsString() == "04/30/2001 06:00:00");
349 t.SetMinute(37);
350 assert(t.AsString() == "04/30/2001 06:37:00");
351 t.SetSecond(59);
352 assert(t.AsString() == "04/30/2001 06:37:59");
353 }}
354
355 // Day of week
356 {{
357 CTime t(1900, 1, 1);
358 int i;
359 for (i = 1; t <= CTime(2030, 12, 31); t.AddDay(),i++) {
360 assert(t.DayOfWeek() == (i%7));
361 }
362 }}
363
364 // Number of days in the month
365 {{
366 CTime t(2000, 1, 31);
367 assert(t.DaysInMonth() == 31);
368 t.SetMonth(2);
369 assert(t.DaysInMonth() == 29);
370 t.SetYear(2001);
371 assert(t.DaysInMonth() == 28);
372 t.SetMonth(4);
373 assert(t.DaysInMonth() == 30);
374 }}
375
376 // Week number in the year/month
377 {{
378 CTime t(1970, 1, 1);
379 int i;
380 char buf[3];
381
382 time_t gt = t.GetTimeT();
383
384 for (i = 1; t <= CTime(2030, 12, 31); i++, t.AddDay(), gt += 24*3600) {
385 struct tm *today = gmtime(>);
386 assert(today != 0);
387 int week_num_rtl, week_num, month_week_num;
388
389 // Sunday-based weeks
390 strftime(buf, sizeof(buf), "%U", today);
391 week_num_rtl = NStr::StringToInt(buf) + 1;
392 week_num = t.YearWeekNumber(/*CTime::eSunday*/);
393 assert(week_num_rtl == week_num);
394 month_week_num = t.MonthWeekNumber(/*CTime::eSunday*/);
395 assert(month_week_num >= 1 && month_week_num <= 6);
396
397 // Monday-based weeks
398 strftime(buf, sizeof(buf), "%W", today);
399 week_num_rtl = NStr::StringToInt(buf) + 1;
400 week_num = t.YearWeekNumber(CTime::eMonday);
401 assert(week_num_rtl == week_num);
402 month_week_num = t.MonthWeekNumber(CTime::eMonday);
403 assert(month_week_num >= 1 && month_week_num <= 6);
404 }
405 }}
406
407 // Rounding time
408 {{
409 CTime::SetFormat("M/D/Y h:m:s.S");
410
411 // Round
412 CTime t(2000, 1, 2, 20, 40, 29, 998933833);
413 t.Round(CTime::eRound_Microsecond);
414 assert(t.AsString() == "01/02/2000 20:40:29.998934000");
415 t.Round(CTime::eRound_Millisecond);
416 assert(t.AsString() == "01/02/2000 20:40:29.999000000");
417 t.Round(CTime::eRound_Second);
418 assert(t.AsString() == "01/02/2000 20:40:30.000000000");
419 t.Round(CTime::eRound_Minute);
420 assert(t.AsString() == "01/02/2000 20:41:00.000000000");
421 t.Round(CTime::eRound_Hour);
422 assert(t.AsString() == "01/02/2000 21:00:00.000000000");
423 t.Round(CTime::eRound_Day);
424 assert(t.AsString() == "01/03/2000 00:00:00.000000000");
425
426 // Round - special case
427 CTime t1(2000, 1, 2, 20, 40, 29, 999999991);
428 t1.Round(CTime::eRound_Microsecond);
429 assert(t1.AsString() == "01/02/2000 20:40:30.000000000");
430
431 // Truncate
432 CTime t2(2000, 1, 2, 20, 40, 29, 998933833);
433 t2.Truncate(CTime::eRound_Microsecond);
434 assert(t2.AsString() == "01/02/2000 20:40:29.998933000");
435 t2.Truncate(CTime::eRound_Millisecond);
436 assert(t2.AsString() == "01/02/2000 20:40:29.998000000");
437 t2.Truncate(CTime::eRound_Second);
438 assert(t2.AsString() == "01/02/2000 20:40:29.000000000");
439 t2.Truncate(CTime::eRound_Minute);
440 assert(t2.AsString() == "01/02/2000 20:40:00.000000000");
441 t2.Truncate(CTime::eRound_Hour);
442 assert(t2.AsString() == "01/02/2000 20:00:00.000000000");
443 t2.Truncate(CTime::eRound_Day);
444 assert(t2.AsString() == "01/02/2000 00:00:00.000000000");
445 }}
446 }
447
448
449 //============================================================================
450 //
451 // TestFormats
452 //
453 //============================================================================
454
s_TestFormats(void)455 static void s_TestFormats(void)
456 {
457 struct SFormatTest {
458 const char* format;
459 int truncated;
460 };
461
462 static const SFormatTest s_Fmt[] = {
463 {"b D Y h:m:s:r", 1},
464 {"b D Y h:m:s:lp", 1},
465 {"b D Y H:m:s P", 1},
466 {"M/D/Y h:m:s", 1},
467 {"M/D/Y h:m:s.S", 0},
468 {"M/D/y h:m:s", 1},
469 {"M/DY h:m:s", 1},
470 {"M/Dy h:m:s", 1},
471 {"M/D/Y hm:s", 1},
472 {"M/D/Y h:ms", 1},
473 {"M/D/Y hms", 1},
474 {"MD/y h:m:s", 1},
475 {"MD/Y h:m:s", 1},
476 {"MYD m:h:s", 1},
477 {"M/D/Y smh", 1},
478 {"YMD h:sm", 1},
479 {"yDM h:ms", 1},
480 {"yMD h:ms", 1},
481 {"D B Y h:m:s", 1},
482 {"B d, Y h:m:s", 1},
483 {"D b Y h:m:s", 1},
484 #if !defined(TIMEZONE_IS_UNDEFINED)
485 {"M/D/Y h:m:s z", 1},
486 #endif
487 {"M/D/Y Z h:m:s", 1},
488 {"M/D/Y h:m:G", 0},
489 {"M/D/Y h:m g", 0},
490 {"smhyMD", 1},
491 {"y||||M++++D h===ms", 1},
492 {" yM[][D h:,.,.,ms ", 1},
493 {"\tkkkMy++D h:ms\n", 1},
494 {0,0}
495 };
496
497 for ( int hour = 0; hour < 24; ++hour ) {
498 for (int i = 0; s_Fmt[i].format; i++) {
499 const char* fmt = s_Fmt[i].format;
500
501 bool is_UTC = (strchr(fmt, 'Z') || strchr(fmt, 'z'));
502 CTime t1(2001, 4, 2, hour, 4, 5, 88888888,
503 is_UTC ? CTime::eUTC : CTime::eLocal);
504
505 CTime::SetFormat(fmt);
506 string t1_str = t1.AsString();
507 CTime::SetFormat("MDY__s");
508 CTime t2(t1_str, fmt);
509 if ( s_Fmt[i].truncated ) {
510 string test_str = t2.AsString("M/D/Y h:m:s");
511 CNcbiOstrstream s;
512 s << "04/02/2001 " << hour/10 << hour%10 << ":04:05";
513 string need_str = CNcbiOstrstreamToString(s);
514 assert(test_str == need_str);
515 } else {
516 assert(t1 == t2);
517 }
518 CTime::SetFormat(fmt);
519 string t2_str = t2;
520 assert(t1_str.compare(t2_str) == 0);
521 assert(CTime::ValidateString(t1_str, fmt));
522 }
523 }
524
525 // Check against well-known dates
526 {{
527 const char fmtstr[] = "M/D/Y h:m:s Z W";
528 {{
529 CTime t(2003, 2, 10, 20, 40, 30, 0, CTime::eUTC);
530 t.SetFormat(fmtstr);
531 string s = t.AsString();
532 assert(s.compare("02/10/2003 20:40:30 GMT Monday") == 0);
533 }}
534 {{
535 CTime t(1998, 2, 10, 20, 40, 30, 0, CTime::eUTC);
536 t.SetFormat(fmtstr);
537 string s = t.AsString();
538 assert(s.compare("02/10/1998 20:40:30 GMT Tuesday") == 0);
539 }}
540 {{
541 CTime t(2003, 3, 13, 15, 49, 30, 0, CTime::eUTC);
542 t.SetFormat(fmtstr);
543 string s = t.AsString();
544 assert(s.compare("03/13/2003 15:49:30 GMT Thursday") == 0);
545 }}
546 {{
547 CTime t(2001, 3, 13, 15, 49, 30, 0, CTime::eUTC);
548 t.SetFormat(fmtstr);
549 string s = t.AsString();
550 assert(s.compare("03/13/2001 15:49:30 GMT Tuesday") == 0);
551 }}
552 {{
553 CTime t(2002, 12, 31, 23, 59, 59, 0, CTime::eUTC);
554 t.SetFormat(fmtstr);
555 string s = t.AsString();
556 assert(s.compare("12/31/2002 23:59:59 GMT Tuesday") == 0);
557 }}
558 {{
559 CTime t(2003, 1, 1, 0, 0, 0, 0, CTime::eUTC);
560 t.SetFormat(fmtstr);
561 string s = t.AsString();
562 assert(s.compare("01/01/2003 00:00:00 GMT Wednesday") == 0);
563 }}
564 {{
565 CTime t(2002, 12, 13, 12, 34, 56, 0, CTime::eUTC);
566 t.SetFormat(fmtstr);
567 string s = t.AsString();
568 assert(s.compare("12/13/2002 12:34:56 GMT Friday") == 0);
569 }}
570 {{
571 CTime t(2003, 2, 10, 20, 40, 30, 0, CTime::eUTC);
572 t.SetFormat(CTimeFormat(fmtstr, CTimeFormat::fConf_UTC));
573 string s = t.AsString();
574 assert(s.compare("02/10/2003 20:40:30 UTC Monday") == 0);
575 }}
576 }}
577 {{
578 const char fmtstr[] = "M/D/Y H:m:s P Z W";
579 {{
580 CTime t(2003, 2, 10, 20, 40, 30, 0, CTime::eUTC);
581 t.SetFormat(fmtstr);
582 string s = t.AsString();
583 assert(s.compare("02/10/2003 08:40:30 PM GMT Monday") == 0);
584 }}
585 {{
586 CTime t(1998, 2, 10, 20, 40, 30, 0, CTime::eUTC);
587 t.SetFormat(fmtstr);
588 string s = t.AsString();
589 assert(s.compare("02/10/1998 08:40:30 PM GMT Tuesday") == 0);
590 }}
591 {{
592 CTime t(2003, 3, 13, 15, 49, 30, 0, CTime::eUTC);
593 t.SetFormat(fmtstr);
594 string s = t.AsString();
595 assert(s.compare("03/13/2003 03:49:30 PM GMT Thursday") == 0);
596 }}
597 {{
598 CTime t(2001, 3, 13, 15, 49, 30, 0, CTime::eUTC);
599 t.SetFormat(fmtstr);
600 string s = t.AsString();
601 assert(s.compare("03/13/2001 03:49:30 PM GMT Tuesday") == 0);
602 }}
603 {{
604 CTime t(2002, 12, 31, 23, 59, 59, 0, CTime::eUTC);
605 t.SetFormat(fmtstr);
606 string s = t.AsString();
607 assert(s.compare("12/31/2002 11:59:59 PM GMT Tuesday") == 0);
608 }}
609 {{
610 CTime t(2003, 1, 1, 0, 0, 0, 0, CTime::eUTC);
611 t.SetFormat(fmtstr);
612 string s = t.AsString();
613 assert(s.compare("01/01/2003 12:00:00 AM GMT Wednesday") == 0);
614 }}
615 {{
616 CTime t(2002, 12, 13, 12, 34, 56, 0, CTime::eUTC);
617 t.SetFormat(fmtstr);
618 string s = t.AsString();
619 assert(s.compare("12/13/2002 12:34:56 PM GMT Friday") == 0);
620 }}
621 }}
622 {{
623 const char fmtstr[] = "b d, Y H:m P";
624 {{
625 CTime t(2003, 2, 10, 20, 40, 30, 0, CTime::eUTC);
626 t.SetFormat(fmtstr);
627 string s = t.AsString();
628 assert(s.compare("Feb 10, 2003 08:40 PM") == 0);
629 }}
630 {{
631 CTime t(1998, 2, 10, 20, 40, 30, 0, CTime::eUTC);
632 t.SetFormat(fmtstr);
633 string s = t.AsString();
634 assert(s.compare("Feb 10, 1998 08:40 PM") == 0);
635 }}
636 {{
637 CTime t(2003, 3, 13, 15, 49, 30, 0, CTime::eUTC);
638 t.SetFormat(fmtstr);
639 string s = t.AsString();
640 assert(s.compare("Mar 13, 2003 03:49 PM") == 0);
641 }}
642 {{
643 CTime t(2001, 3, 13, 15, 49, 30, 0, CTime::eUTC);
644 t.SetFormat(fmtstr);
645 string s = t.AsString();
646 assert(s.compare("Mar 13, 2001 03:49 PM") == 0);
647 }}
648 {{
649 CTime t(2002, 12, 31, 23, 59, 59, 0, CTime::eUTC);
650 t.SetFormat(fmtstr);
651 string s = t.AsString();
652 assert(s.compare("Dec 31, 2002 11:59 PM") == 0);
653 }}
654 {{
655 CTime t(2003, 1, 1, 0, 0, 0, 0, CTime::eUTC);
656 t.SetFormat(fmtstr);
657 string s = t.AsString();
658 assert(s.compare("Jan 1, 2003 12:00 AM") == 0);
659 }}
660 {{
661 CTime t(2002, 12, 13, 12, 34, 56, 0, CTime::eUTC);
662 t.SetFormat(fmtstr);
663 string s = t.AsString();
664 assert(s.compare("Dec 13, 2002 12:34 PM") == 0);
665 }}
666 }}
667
668 // Partially defined time
669 {{
670 string s;
671 {{ // Y
672 CTime t("2001", "Y");
673 s = t.AsString("M/D/Y h:m:s");
674 assert(s.compare("01/01/2001 00:00:00") == 0);
675 }}
676 {{ // Y/M
677 CTime t("2001/2", "Y/M");
678 s = t.AsString("M/D/Y h:m:s");
679 assert(s.compare("02/01/2001 00:00:00") == 0);
680 }}
681 {{ // M/D
682 CTime current(CTime::eCurrent);
683 current.Truncate();
684 CTime t("01/02", "M/D");
685 current.SetMonth(1);
686 current.SetDay(2);
687 assert(t == current);
688 }}
689 {{ // M
690 CTime current(CTime::eCurrent);
691 current.Truncate();
692 CTime t("2", "M");
693 current.SetMonth(2);
694 current.SetDay(1);
695 assert(t == current);
696 }}
697 {{ // D time
698 CTime current(CTime::eCurrent);
699 current.Truncate();
700 CTime t("2 11:22", "D h:m");
701 current.SetDay(2);
702 current.SetHour(11);
703 current.SetMinute(22);
704 assert(t == current);
705 }}
706 {{ // D
707 CTime current(CTime::eCurrent);
708 current.Truncate();
709 CTime t("2", "D");
710 current.SetDay(2);
711 assert(t == current);
712 }}
713 {{ // time
714 CTime current(CTime::eCurrent);
715 CTime t("11:22", "h:m");
716 current.SetHour(11);
717 current.SetMinute(22);
718 current.SetSecond(0);
719 current.SetNanoSecond(0);
720 assert(t == current);
721 }}
722
723 try {
724 CTime t("2001/2 00:00", "Y/M h:m");
725 _TROUBLE; // day is not defined
726 t.Clear();
727 }
728 catch (CTimeException&) {}
729
730 try {
731 CTime t("2001/2 00:00", "Y/D h:m");
732 _TROUBLE; // month is not defined
733 t.Clear();
734 }
735 catch (CTimeException&) {}
736
737 try {
738 CTime t("2001/2", "Y/D");
739 _TROUBLE; // month is not defined
740 t.Clear();
741 }
742 catch (CTimeException&) {}
743
744 try {
745 CTime t("2001 00:00", "Y h:m");
746 _TROUBLE; // month and day are not defined
747 t.Clear();
748 }
749 catch (CTimeException&) {}
750
751 try {
752 CTime t("2 00:00", "M h:m");
753 _TROUBLE; // year and day are not defined
754 t.Clear();
755 }
756 catch (CTimeException&) {}
757 }}
758
759 // Strict/weak time assignment from a string
760 {{
761 string s;
762 {{
763 CTime t("2001", CTimeFormat("Y/M/D", CTimeFormat::fMatch_ShortTime));
764 s = t.AsString("M/D/Y h:m:s");
765 assert(s.compare("01/01/2001 00:00:00") == 0);
766 }}
767 {{
768 // Note that day and month changed
769 CTime t("2001/01/02", CTimeFormat("Y", CTimeFormat::fMatch_ShortFormat));
770 s = t.AsString("M/D/Y h:m:s");
771 assert(s.compare("01/01/2001 00:00:00") == 0);
772 }}
773 {{
774 CTime t("2001", CTimeFormat("Y/M/D", CTimeFormat::fMatch_Weak));
775 s = t.AsString("M/D/Y h:m:s");
776 assert(s.compare("01/01/2001 00:00:00") == 0);
777 }}
778 {{
779 try {
780 CTime t("2001...", CTimeFormat("Y/M/D", CTimeFormat::fMatch_Weak));
781 s = t.AsString("M/D/Y h:m:s");
782 assert(s.compare("01/01/2001 00:00:00") == 0);
783 }
784 catch (CTimeException&) {}
785 }}
786 {{
787 try {
788 CTime t("2001/01/02", CTimeFormat("Y...", CTimeFormat::fMatch_Weak));
789 s = t.AsString("M/D/Y h:m:s");
790 assert(s.compare("01/01/2001 00:00:00") == 0);
791 }
792 catch (CTimeException&) {}
793 }}
794 // Check that strict matching is by default.
795 {{
796 try {
797 CTime t("2001", "Y/M/D");
798 _TROUBLE; // by default used strict format matching
799 t.Clear();
800 }
801 catch (CTimeException&) {}
802 try {
803 CTime t("2001/01/02", "Y");
804 _TROUBLE; // by default used strict format matching
805 t.Clear();
806 }
807 catch (CTimeException&) {}
808 }}
809 }}
810
811 // Observing spaces by default. Make sure that:
812 // - if fields in the format string are separated by one or more
813 // white spaces, then the fields in the parsed string also must
814 // be separated by one or more spaces;
815 // - if fields in the format string are adjacent, then the fields
816 // in the parsed string also must be adjacent.
817 //
818 // fMatch_IgnoreSpaces changes default behavior to backward-compatible.
819 //
820 // JIRA: CXX-5422
821 {{
822 CTimeFormat::EFlags ign = (CTimeFormat::EFlags)(CTimeFormat::fDefault |
823 CTimeFormat::fMatch_IgnoreSpaces);
824
825 // default flags
826 assert( CTime::ValidateString("01/01/2001", CTimeFormat("M/D/Y") ));
827 assert(! CTime::ValidateString("01/01/2001 ", CTimeFormat("M/D/Y") ));
828 assert( CTime::ValidateString("01/01/2001 ", CTimeFormat("M/D/Y ") ));
829 assert( CTime::ValidateString("01012001", CTimeFormat("MDY") ));
830 assert( !CTime::ValidateString("01 01 2001", CTimeFormat("MDY") ));
831 assert( CTime::ValidateString("01 01 2001", CTimeFormat("M D Y") ));
832 assert( !CTime::ValidateString(" 01 01 2001", CTimeFormat("M D Y") ));
833 assert( !CTime::ValidateString("01 01 2001 ", CTimeFormat("M D Y") ));
834 assert( CTime::ValidateString("01 01 2001", CTimeFormat("M D Y") ));
835 assert( !CTime::ValidateString("01 01 2001 ", CTimeFormat("M D Y") ));
836 assert( CTime::ValidateString("01\n01\t2001", CTimeFormat("M D Y") ));
837 assert( CTime::ValidateString("01\n 01\t2001", CTimeFormat("M D Y") ));
838 assert( CTime::ValidateString("01 01 2001 ", CTimeFormat("M D Y ") ));
839 assert( CTime::ValidateString("01 01 2001 ", CTimeFormat("M D Y ") ));
840 assert( CTime::ValidateString(" 0101 2001", CTimeFormat(" MD Y") ));
841 assert( CTime::ValidateString(" 0101 2001", CTimeFormat(" MD Y") ));
842 assert( !CTime::ValidateString(" 0101 2001 ", CTimeFormat("MDY") ));
843 assert( !CTime::ValidateString("01/01/2001\n\n", CTimeFormat("M/D/Y") ));
844 assert( CTime::ValidateString("01/01/2001\n\n", CTimeFormat("M/D/Y ") ));
845
846 // "short" flags
847 assert( CTime::ValidateString("01/01/2001\n\n", CTimeFormat("M/D/Y",
848 CTimeFormat::fMatch_ShortFormat)));
849 assert( CTime::ValidateString("01/01/2001", CTimeFormat("M/D/Y ",
850 CTimeFormat::fMatch_ShortTime)));
851 // fMatch_IgnoreSpaces -- all valid
852 assert( CTime::ValidateString("01/01/2001", CTimeFormat("M/D/Y", ign) ));
853 assert( CTime::ValidateString("01/01/2001 ", CTimeFormat("M/D/Y", ign) ));
854 assert( CTime::ValidateString("01/01/2001 ", CTimeFormat("M/D/Y ", ign) ));
855 assert( CTime::ValidateString("01012001", CTimeFormat("MDY", ign) ));
856 assert( CTime::ValidateString("01 01 2001", CTimeFormat("MDY", ign) ));
857 assert( CTime::ValidateString("01 01 2001", CTimeFormat("M D Y", ign) ));
858 assert( CTime::ValidateString(" 01 01 2001", CTimeFormat("M D Y", ign) ));
859 assert( CTime::ValidateString("01 01 2001 ", CTimeFormat("M D Y", ign) ));
860 assert( CTime::ValidateString("01 01 2001", CTimeFormat("M D Y", ign) ));
861 assert( CTime::ValidateString("01 01 2001 ", CTimeFormat("M D Y", ign) ));
862 assert( CTime::ValidateString("01\n01\t2001", CTimeFormat("M D Y", ign) ));
863 assert( CTime::ValidateString("01\n 01\t2001", CTimeFormat("M D Y", ign) ));
864 assert( CTime::ValidateString("01 01 2001 ", CTimeFormat("M D Y ", ign) ));
865 assert( CTime::ValidateString("01 01 2001 ", CTimeFormat("M D Y ",ign) ));
866 assert( CTime::ValidateString(" 0101 2001", CTimeFormat(" MD Y", ign) ));
867 assert( CTime::ValidateString(" 0101 2001", CTimeFormat(" MD Y", ign) ));
868 assert( CTime::ValidateString(" 0101 2001 ", CTimeFormat("MDY", ign) ));
869 assert( CTime::ValidateString("01/01/2001\n\n", CTimeFormat("M/D/Y", ign) ));
870 assert( CTime::ValidateString("01/01/2001\n\n", CTimeFormat("M/D/Y ", ign) ));
871 }}
872
873 // SetFormat/AsString with flag parameter test
874 {{
875 CTime t(2003, 2, 10, 20, 40, 30, 0, CTime::eUTC);
876 string s;
877 s = t.AsString("M/D/Y h:m:s");
878 assert(s.compare("02/10/2003 20:40:30") == 0);
879 s = t.AsString("MDY $M/$D/$Y $h:$m:$s hms");
880 assert(s.compare("02102003 $02/$10/$2003 $20:$40:$30 204030") == 0);
881 s = t.AsString(CTimeFormat("MDY $M/$D/$Y $h:$m:$s hms", CTimeFormat::eNcbi));
882 assert(s.compare("MDY 02/10/2003 20:40:30 hms") == 0);
883 s = t.AsString(CTimeFormat("$YY $MM $dd $hh $mm $ss", CTimeFormat::eNcbi));
884 assert(s.compare("2003Y 02M 10d 20h 40m 30s") == 0);
885 }}
886
887 // CTimeFormat::GetPredefined() test
888 {{
889 CTime t(2003, 2, 10, 20, 40, 30, 123, CTime::eUTC);
890 string s;
891 s = t.AsString(CTimeFormat::GetPredefined(CTimeFormat::eISO8601_Year));
892 assert(s.compare("2003") == 0);
893 s = t.AsString(CTimeFormat::GetPredefined(CTimeFormat::eISO8601_YearMonth));
894 assert(s.compare("2003-02") == 0);
895 s = t.AsString(CTimeFormat::GetPredefined(CTimeFormat::eISO8601_Date));
896 assert(s.compare("2003-02-10") == 0);
897 s = t.AsString(CTimeFormat::GetPredefined(CTimeFormat::eISO8601_DateTimeMin));
898 assert(s.compare("2003-02-10T20:40") == 0);
899 s = t.AsString(CTimeFormat::GetPredefined(CTimeFormat::eISO8601_DateTimeSec));
900 assert(s.compare("2003-02-10T20:40:30") == 0);
901 s = t.AsString(CTimeFormat::GetPredefined(CTimeFormat::eISO8601_DateTimeFrac));
902 assert(s.compare("2003-02-10T20:40:30.000000123") == 0);
903 }}
904 // CTimeFormat::GetPredefined( eISO8601_DateTimeFrac ) test
905 {{
906 CTime t(2003, 2, 10, 20, 40, 3, 0, CTime::eLocal);
907 CTimeFormat fmt = CTimeFormat::GetPredefined(CTimeFormat::eISO8601_DateTimeFrac);
908 t.SetNanoSecond(0);
909 assert(t.AsString(fmt) == "2003-02-10T20:40:03.0");
910 t.SetNanoSecond(2);
911 assert(t.AsString(fmt) == "2003-02-10T20:40:03.000000002");
912 t.SetNanoSecond(1234);
913 assert(t.AsString(fmt) == "2003-02-10T20:40:03.000001234");
914 t.SetNanoSecond(123456789);
915 assert(t.AsString(fmt) == "2003-02-10T20:40:03.123456789");
916 t.SetNanoSecond(123000);
917 assert(t.AsString(fmt) == "2003-02-10T20:40:03.000123");
918 t.SetNanoSecond(123000000);
919 assert(t.AsString(fmt) == "2003-02-10T20:40:03.123");
920 }}
921
922 // Test assignment operator in different (from default) time format
923 {{
924 CTime t0(2003, 2, 10, 20, 40, 30, 0, CTime::eLocal);
925 CTime::SetFormat(CTimeFormat::GetPredefined(
926 CTimeFormat::eISO8601_DateTimeMin,
927 CTimeFormat::eNcbi));
928 assert(t0.AsString() == "2003-02-10T20:40");
929 CTime t("2003-02-10T20:40");
930 t.SetSecond(30);
931 assert(t == t0);
932 }}
933
934 // Formats with floating numbers of seconds ("g", "G")
935 {{
936 CTime t;
937 {{
938 t.SetFormat("g");
939 t = "3";
940 assert(t.AsString() == "3.0");
941 assert(t.AsString("s.S") == "03.000000000");
942 t = "3.45";
943 assert(t.AsString() == "3.45");
944 assert(t.AsString("s.S") == "03.450000000");
945 // long string with ignored symbols after 9th digit.
946 t = "3.123456789123456";
947 assert(t.AsString() == "3.123456789");
948 assert(t.AsString("s.S") == "03.123456789");
949 }}
950 {{
951 t.SetFormat("G");
952 t = "3";
953 assert(t.AsString() == "03.0");
954 assert(t.AsString("s.S") == "03.000000000");
955 t = "3.45";
956 assert(t.AsString() == "03.45");
957 assert(t.AsString("s.S") == "03.450000000");
958 // long string with ignored symbols after 9th digit.
959 t = "3.123456789123456";
960 assert(t.AsString() == "03.123456789");
961 assert(t.AsString("s.S") == "03.123456789");
962 }}
963 }}
964
965 // AM/PM time parsing
966 {{
967 CTime t;
968 t.SetFormat("Y-M-D H:m P");
969 string fmtout = "Y-M-D h:m";
970 t = "2001-01-01 12:00 AM"; assert(t.AsString(fmtout) == "2001-01-01 00:00");
971 t = "2001-01-01 12:01 AM"; assert(t.AsString(fmtout) == "2001-01-01 00:01");
972 t = "2001-01-01 01:00 AM"; assert(t.AsString(fmtout) == "2001-01-01 01:00");
973 t = "2001-01-01 11:00 AM"; assert(t.AsString(fmtout) == "2001-01-01 11:00");
974 t = "2001-01-01 11:59 AM"; assert(t.AsString(fmtout) == "2001-01-01 11:59");
975 t = "2001-01-01 12:00 PM"; assert(t.AsString(fmtout) == "2001-01-01 12:00");
976 t = "2001-01-01 12:01 PM"; assert(t.AsString(fmtout) == "2001-01-01 12:01");
977 t = "2001-01-01 01:00 PM"; assert(t.AsString(fmtout) == "2001-01-01 13:00");
978 t = "2001-01-01 11:00 PM"; assert(t.AsString(fmtout) == "2001-01-01 23:00");
979 t = "2001-01-01 11:59 PM"; assert(t.AsString(fmtout) == "2001-01-01 23:59");
980 }}
981 }
982
983
984 //============================================================================
985 //
986 // Test UTC/GMT
987 //
988 //============================================================================
989
s_TestUTC(void)990 static void s_TestUTC(void)
991 {
992 //------------------------------------------------------------------------
993 // Local/universal times
994 {{
995 CTime::SetFormat("M/D/Y h:m:s Z");
996 CTime t1(2001, 3, 12, 11, 22, 33, 999, CTime::eUTC);
997 assert(t1.AsString() == "03/12/2001 11:22:33 GMT");
998 CTime t2(2001, 3, 12, 11, 22, 33, 999, CTime::eLocal);
999 assert(t2.AsString() == "03/12/2001 11:22:33 ");
1000
1001 CTime::SetFormat(CTimeFormat("M/D/Y h:m:s Z", CTimeFormat::fConf_UTC));
1002 CTime t3(2001, 3, 12, 11, 22, 33, 999, CTime::eUTC);
1003 assert(t1.AsString() == "03/12/2001 11:22:33 UTC");
1004
1005 // Current time
1006 CTime tl(CTime::eCurrent, CTime::eLocal);
1007 CTime tu(CTime::eCurrent, CTime::eUTC);
1008 CCurrentTime cl(CTime::eLocal);
1009 CCurrentTime cu(CTime::eUTC);
1010 }}
1011 //------------------------------------------------------------------------
1012 // Process timezone string
1013 {{
1014 CTime t;
1015 t.SetFormat("M/D/Y h:m:s Z");
1016 t = "03/12/2001 11:22:33 UTC";
1017 assert(t.AsString() == "03/12/2001 11:22:33 GMT");
1018 t = "03/12/2001 11:22:33 GMT";
1019 assert(t.AsString() == "03/12/2001 11:22:33 GMT");
1020 t = "03/12/2001 11:22:33 Z";
1021 assert(t.AsString() == "03/12/2001 11:22:33 GMT");
1022 t = "03/12/2001 11:22:33 ";
1023 assert(t.AsString() == "03/12/2001 11:22:33 ");
1024 }}
1025 //------------------------------------------------------------------------
1026 // Day of week
1027 {{
1028 CTime t(2001, 4, 1);
1029 t.SetFormat("M/D/Y h:m:s w");
1030 int i;
1031 for (i = 0; t <= CTime(2001, 4, 10); t.AddDay(),i++) {
1032 assert(t.DayOfWeek() == (i%7));
1033 }
1034 }}
1035 //------------------------------------------------------------------------
1036 // Test GetTimeT
1037 {{
1038
1039 time_t timer = time(0);
1040 CTime tgmt(CTime::eCurrent, CTime::eUTC, CTime::eTZPrecisionDefault);
1041 CTime tloc(CTime::eCurrent, CTime::eLocal, CTime::eTZPrecisionDefault);
1042 CTime t(timer);
1043 // Set the same time to all time objects
1044 tgmt.SetTimeT(timer);
1045 tloc.SetTimeT(timer);
1046
1047 time_t g_ = tgmt.GetTimeT();
1048 time_t l_ = tloc.GetTimeT();
1049 time_t t_ = t.GetTimeT();
1050
1051 ERR_POST(Note << STR(t));
1052 ERR_POST(Note << NStr::Int8ToString(g_/3600) + " - " +
1053 NStr::Int8ToString(l_/3600) + " - " +
1054 NStr::Int8ToString(t_/3600) + " - " +
1055 NStr::Int8ToString(timer/3600) + "\n");
1056
1057 assert(timer == t_);
1058 assert(timer == g_);
1059 // On the day of changing to summer/winter time, the local time
1060 // converted to UTC may differ from the value returned by time(0),
1061 // because in the common case API don't know is DST in effect for
1062 // specified local time or not (see mktime()).
1063 if (timer != l_) {
1064 if ( abs((int)(timer - l_)) > 3600 )
1065 assert(timer == l_);
1066 }
1067
1068 CTime t11(2013, 3, 10, 1, 59, 0, 0, CTime::eLocal, CTime::eHour);
1069 CTime t12(2013, 3, 10, 3, 0, 0, 0, CTime::eLocal, CTime::eHour);
1070 assert(t12.GetTimeT()/3600 - t11.GetTimeT()/3600 == 1);
1071
1072 CTime t21(2013, 11, 3, 0, 59, 0, 0, CTime::eLocal, CTime::eHour);
1073 CTime t22(2013, 11, 3, 2, 0, 0, 0, CTime::eLocal, CTime::eHour);
1074 assert(t22.GetTimeT()/3600 - t21.GetTimeT()/3600 == 3);
1075
1076 // Check for underlying implementations not based on time_t (Win/Unix).
1077 // Results should be close, but not necessary equal,
1078 // and even 'timer' can be greater than 'now'.
1079 // On Linux this behavior is due to the implementation of timekeeping
1080 // in the kernel. Note: time() is called after gettimeofday()
1081 // (GetCurrentTimeT()) on Unix.
1082 t.GetCurrentTimeT(&timer);
1083 time_t now = time(0);
1084 if (timer < now) {
1085 assert(now - timer < 3);
1086 } else {
1087 assert(timer - now < 3);
1088 }
1089 }}
1090
1091 //------------------------------------------------------------------------
1092 // Test GetTimeTM
1093 {{
1094 CTime tloc(CTime::eCurrent, CTime::eLocal, CTime::eTZPrecisionDefault);
1095 struct tm l_ = tloc.GetTimeTM();
1096 CTime tmp(CTime::eCurrent, CTime::eUTC, CTime::eTZPrecisionDefault);
1097 assert(tmp.GetTimeZone() == CTime::eUTC);
1098 tmp.SetTimeTM(l_);
1099 assert(tmp.GetTimeZone() == CTime::eLocal);
1100 assert(tloc.AsString() == tmp.AsString());
1101
1102 CTime tgmt(tloc.GetTimeT());
1103 struct tm g_ = tgmt.GetTimeTM();
1104 tmp.SetTimeTM(g_);
1105 assert(tmp.GetTimeZone() == CTime::eLocal);
1106 assert(tgmt.AsString() != tloc.AsString());
1107 }}
1108 //------------------------------------------------------------------------
1109 // Test TimeZoneOffset (1) -- EST timezone only
1110 {{
1111 CTime tw(2001, 1, 1, 12);
1112 CTime ts(2001, 6, 1, 12);
1113 assert(tw.TimeZoneOffset() / 3600 == -5);
1114 assert(ts.TimeZoneOffset() / 3600 == -4);
1115 tw.SetFormat("M/D/Y");
1116 for (; tw < ts; tw.AddDay()) {
1117 if ((tw.TimeZoneOffset() / 3600) == -4) {
1118 ERR_POST(Note << "First daylight saving day = " + STR(tw));
1119 break;
1120 }
1121 }
1122 }}
1123 //------------------------------------------------------------------------
1124 // Test TimeZoneOffset (2) -- EST timezone only
1125 {{
1126 CTime tw(2001, 6, 1, 12);
1127 CTime ts(2002, 1, 1, 12);
1128 assert(tw.TimeZoneOffset() / 3600 == -4);
1129 assert(ts.TimeZoneOffset() / 3600 == -5);
1130 tw.SetFormat("M/D/Y");
1131 for (; tw < ts; tw.AddDay()) {
1132 if ((tw.TimeZoneOffset() / 3600) == -5) {
1133 ERR_POST(Note << "First non daylight saving day = " + STR(tw));
1134 break;
1135
1136 }
1137 }
1138 }}
1139 //------------------------------------------------------------------------
1140 // Test AdjusyTime -- EST timezone only
1141 {{
1142 CTime::SetFormat("M/D/Y h:m:s");
1143 CTime t("03/11/2007 01:01:00");
1144 CTime tn;
1145 t.SetTimeZonePrecision(CTime::eTZPrecisionDefault);
1146
1147 t.SetTimeZone(CTime::eUTC);
1148 tn = t;
1149 tn.AddDay(5);
1150 assert(tn.AsString() == "03/16/2007 01:01:00");
1151 tn = t;
1152 tn.AddDay(40);
1153 assert(tn.AsString() == "04/20/2007 01:01:00");
1154
1155 t.SetTimeZone(CTime::eLocal);
1156 t.SetTimeZonePrecision(CTime::eNone);
1157 tn = t;
1158 tn.AddDay(5);
1159 assert(tn.AsString() == "03/16/2007 01:01:00");
1160 tn = t;
1161 tn.AddDay(40);
1162 assert(tn.AsString() == "04/20/2007 01:01:00");
1163
1164 t.SetTimeZonePrecision(CTime::eMonth);
1165 tn = t;
1166 tn.AddDay(5);
1167 tn = t;
1168 tn.AddMonth(-1);
1169 assert(tn.AsString() == "02/11/2007 01:01:00");
1170 tn = t;
1171 tn.AddMonth(+1);
1172 assert(tn.AsString() == "04/11/2007 02:01:00");
1173
1174 t.SetTimeZonePrecision(CTime::eDay);
1175 tn = t;
1176 tn.AddDay(-1);
1177 assert(tn.AsString() == "03/10/2007 01:01:00");
1178 tn.AddDay();
1179 assert(tn.AsString() == "03/11/2007 01:01:00");
1180 tn = t;
1181 tn.AddDay();
1182 assert(tn.AsString() == "03/12/2007 02:01:00");
1183
1184 t.SetTimeZonePrecision(CTime::eHour);
1185 tn = t;
1186 tn.AddHour(-3);
1187 CTime te = t;
1188 te.AddHour(3);
1189 assert(tn.AsString() == "03/10/2007 22:01:00");
1190 assert(te.AsString() == "03/11/2007 05:01:00");
1191 CTime th = tn;
1192 th.AddHour(49);
1193 assert(th.AsString() == "03/13/2007 00:01:00");
1194
1195 tn = "11/04/2007 00:01:00";
1196 tn.SetTimeZonePrecision(CTime::eHour);
1197 te = tn;
1198 tn.AddHour(-3);
1199 te.AddHour(9);
1200 assert(tn.AsString() == "11/03/2007 21:01:00");
1201 assert(te.AsString() == "11/04/2007 08:01:00");
1202 th = tn;
1203 th.AddHour(49);
1204 assert(th.AsString() == "11/05/2007 21:01:00");
1205
1206 tn = "11/04/2007 09:01:00";
1207 tn.SetTimeZonePrecision(CTime::eHour);
1208 te = tn;
1209 tn.AddHour(-10);
1210 te.AddHour(+10);
1211 assert(tn.AsString() == "11/04/2007 00:01:00");
1212 assert(te.AsString() == "11/04/2007 19:01:00");
1213 }}
1214 }
1215
1216
1217 //============================================================================
1218 //
1219 // TestUTCSpeed
1220 //
1221 //============================================================================
1222
1223 #if ENABLE_SPEED_TESTS
1224
s_TestUTCSpeedRun(string comment,CTime::ETimeZone tz,CTime::ETimeZonePrecision tzp)1225 static void s_TestUTCSpeedRun(string comment, CTime::ETimeZone tz,
1226 CTime::ETimeZonePrecision tzp)
1227 {
1228 CTime t(CTime::eCurrent, tz, tzp);
1229 CStopWatch timer;
1230
1231 #if defined NCBI_OS_MSWIN
1232 const long kCount=100000L;
1233 #elif defined NCBI_OS_UNIX
1234 const long kCount=10000L;
1235 #else
1236 const long kCount=100000L;
1237 #endif
1238
1239 t.SetFormat("M/D/Y h:m:s");
1240 t = "03/31/2001 00:00:00";
1241
1242 timer.Start();
1243 for (long i = 0; i < kCount; i++) {
1244 t.AddMinute();
1245 }
1246 ERR_POST(Note << comment + ", duration = " + NStr::DoubleToString(timer.Elapsed()) + " sec.");
1247 }
1248
s_TestUTCSpeed(void)1249 static void s_TestUTCSpeed(void)
1250 {
1251 s_TestUTCSpeedRun("eLocal - eMinute", CTime::eLocal, CTime::eMinute);
1252 s_TestUTCSpeedRun("eLocal - eHour ", CTime::eLocal, CTime::eHour);
1253 s_TestUTCSpeedRun("eLocal - eMonth ", CTime::eLocal, CTime::eMonth);
1254 s_TestUTCSpeedRun("eLocal - eNone ", CTime::eLocal, CTime::eNone);
1255 s_TestUTCSpeedRun("eUTC - eNone ", CTime::eUTC, CTime::eNone);
1256 }
1257
1258 #endif
1259
1260 //============================================================================
1261 //
1262 // TestTimeSpan
1263 //
1264 //============================================================================
1265
s_TestTimeSpan(void)1266 static void s_TestTimeSpan(void)
1267 {
1268 // Common constructors
1269 {{
1270 CTimeSpan t1(0,0,0,1,-2);
1271 assert(t1.AsString() == "0.999999998");
1272 CTimeSpan t2(0,0,0,-1,2);
1273 assert(t2.AsString() == "-0.999999998");
1274 CTimeSpan t3(0,0,0,0,-2);
1275 assert(t3.AsString() == "-0.000000002");
1276 CTimeSpan t4(0,0,0,0,2);
1277 assert(t4.AsString() == "0.000000002");
1278 }}
1279 {{
1280 CTimeSpan t1(2,3,4,5,6);
1281 assert(t1.GetCompleteHours() == 51);
1282 assert(t1.GetCompleteMinutes() == (51*60+4));
1283 assert(t1.GetCompleteSeconds() == ((51*60+4)*60+5));
1284 assert(t1.GetNanoSecondsAfterSecond() == 6);
1285 assert(t1.AsString() == "183845.000000006");
1286
1287 CTimeSpan t2(-2,-3,-4,-5,-6);
1288 assert(t2.GetCompleteHours() == -51);
1289 assert(t2.GetCompleteMinutes() == -(51*60+4));
1290 assert(t2.GetCompleteSeconds() == -((51*60+4)*60+5));
1291 assert(t2.GetNanoSecondsAfterSecond() == -6);
1292 assert(t2.AsString() == "-183845.000000006");
1293
1294 CTimeSpan t3(-2,+3,-4,-5,+6);
1295 assert(t3.GetCompleteHours() == -45);
1296 assert(t3.GetCompleteMinutes() == -(45*60+4));
1297 assert(t3.GetCompleteSeconds() == -((45*60+4)*60+4));
1298 assert(t3.GetNanoSecondsAfterSecond() == -999999994);
1299 assert(t3.AsString() == "-162244.999999994");
1300 }}
1301
1302 // Comparison
1303 {{
1304 CTimeSpan t0;
1305 CTimeSpan t1(123.4);
1306 CTimeSpan t2(123.45);
1307 CTimeSpan t3(123.4);
1308
1309 assert(t0.GetSign() == eZero);
1310 assert(t1.GetSign() == ePositive);
1311 assert(t0 == CTimeSpan(0,0,0,0,0));
1312 assert(t1 != t2);
1313 assert(t1 == t3);
1314 assert(t1 < t2);
1315 assert(t2 > t1);
1316 assert(t1 <= t2);
1317 assert(t2 >= t2);
1318 }}
1319
1320 // Assignment
1321 {{
1322 CTimeSpan t1(-123.4);
1323 CTimeSpan t2(123.45);
1324
1325 t1 = t2;
1326 assert(t1 == t2);
1327 t1 = "-123.450000000";
1328 assert(t1 == -t2);
1329 }}
1330
1331 // Arithmetics
1332 {{
1333 // This case test defaut behavior -- SetFormat() never used before!
1334 // and "-G" is format by default to init from strings in this case.
1335 {{
1336 CTimeSpan t;
1337 t = CTimeSpan("100.3") - CTimeSpan("123.4");
1338 assert(t == CTimeSpan("-23.1"));
1339 t = CTimeSpan("63.7") + CTimeSpan("2.3");
1340 assert(t == CTimeSpan("66"));
1341 t = CTimeSpan("63.7") - CTimeSpan("72.6");
1342 assert(t == CTimeSpan("-8.9"));
1343
1344 t = "-123.4";
1345 t += CTimeSpan("1.0");
1346 assert(t == CTimeSpan("-122.4"));
1347 t += CTimeSpan("222.4");
1348 assert(t == CTimeSpan("100.0") );
1349 t -= CTimeSpan("50.1");
1350 assert(t == CTimeSpan("49.9"));
1351 t += CTimeSpan("0.1");
1352 assert(t == CTimeSpan("50.0"));
1353 t += CTimeSpan("3.7");
1354 assert(t == CTimeSpan("53.7"));
1355 t -= CTimeSpan("3.8");
1356 assert(t == CTimeSpan("49.9"));
1357 }}
1358 // And now the same with another format "-S.n".
1359 {{
1360 CTimeSpan::SetFormat("-S.n");
1361 CTimeSpan t;
1362 t = CTimeSpan("100.3") - CTimeSpan("123.4");
1363 assert(t == CTimeSpan("-23.1"));
1364 t = CTimeSpan("63.7") + CTimeSpan("2.3");
1365 assert(t == CTimeSpan("65.10"));
1366 t = CTimeSpan("63.7") - CTimeSpan("72.6");
1367 assert(t == CTimeSpan("-8.999999999"));
1368
1369 t = "-123.4";
1370 t += CTimeSpan("1.0");
1371 assert(t == CTimeSpan("-122.4"));
1372 t += CTimeSpan("222.4");
1373 assert(t == CTimeSpan("100.0") );
1374 t -= CTimeSpan("50.1");
1375 assert(t == CTimeSpan("49.999999999"));
1376 t += CTimeSpan("0.1");
1377 assert(t == CTimeSpan("50.0"));
1378 t += CTimeSpan("3.7");
1379 assert(t == CTimeSpan("53.7"));
1380 t -= CTimeSpan("3.8");
1381 assert(t == CTimeSpan("49.999999999"));
1382 }}
1383 }}
1384
1385 // Formats with floating numbers of seconds ("g", "G")
1386 {{
1387 CTimeSpan t;
1388 {{
1389 t.SetFormat("g");
1390 t = "123";
1391 assert(t.AsString() == "3.0");
1392 assert(t.AsString("s.n") == "03.000000000");
1393 t = "123.45";
1394 assert(t.AsString() == "3.45");
1395 assert(t.AsString("s.n") == "03.450000000");
1396 // long string with ignored symbols after 9th digit.
1397 t = "123.123456789123456";
1398 assert(t.AsString() == "3.123456789");
1399 assert(t.AsString("s.n") == "03.123456789");
1400 }}
1401 {{
1402 t.SetFormat("G");
1403 t = "123";
1404 assert(t.AsString() == "123.0");
1405 assert(t.AsString("S.n") == "123.000000000");
1406 t = "123.45";
1407 assert(t.AsString() == "123.45");
1408 assert(t.AsString("S.n") == "123.450000000");
1409 // long string with ignored symbols after 9th digit.
1410 t = "123.123456789123456";
1411 assert(t.AsString() == "123.123456789");
1412 assert(t.AsString("S.n") == "123.123456789");
1413 }}
1414 }}
1415
1416 // Formats
1417 {{
1418 static const char* s_Fmt[] = {
1419 "d h:m:s.n",
1420 "H m:s",
1421 "S",
1422 "H",
1423 "M",
1424 "d",
1425 "G",
1426 "g",
1427 "-d h:m:s.n",
1428 "-H m:s",
1429 "-S",
1430 "-H",
1431 "-M",
1432 "-d",
1433 "-G",
1434 "-g",
1435 0
1436 };
1437
1438 for (const char** fmt = s_Fmt; *fmt; fmt++) {
1439 CTimeSpan t1(-123456789.987654321);
1440 CTimeSpan::SetFormat(*fmt);
1441 string t1_str = t1.AsString();
1442 CTimeSpan::SetFormat("_s_");
1443 CTimeSpan t2(t1_str, *fmt);
1444 CTimeSpan::SetFormat(*fmt);
1445 string t2_str = t2;
1446 assert(t1_str.compare(t2_str) == 0);
1447 }
1448 }}
1449
1450 // SetFormat/AsString with flag parameter test
1451 {{
1452 CTimeSpan t(123.456);
1453 string s;
1454 s = t.AsString("S.n");
1455 assert(s.compare("123.456000000") == 0);
1456 s = t.AsString("$S.$n");
1457 assert(s.compare("$123.$456000000") == 0);
1458 s = t.AsString(CTimeFormat("$S.$n", CTimeFormat::eNcbi));
1459 assert(s.compare("123.456000000") == 0);
1460 s = t.AsString(CTimeFormat("$mm $ss", CTimeFormat::eNcbi));
1461 assert(s.compare("02m 03s") == 0);
1462 }}
1463 }
1464
1465
1466
1467 //============================================================================
1468 //
1469 // TestTimeSpan -- AssignFromSmartString()
1470 // Cases not covered by converting strings produced by AsSmartString().
1471 //
1472 //============================================================================
1473
s_TestTimeSpan_AssignFromSmartString(void)1474 static void s_TestTimeSpan_AssignFromSmartString(void)
1475 {
1476 struct STest {
1477 const char* str;
1478 CTimeSpan result;
1479 };
1480
1481 static const STest s_Test[] = {
1482 { "", CTimeSpan() },
1483 { " ", CTimeSpan() },
1484 { "\t", CTimeSpan() },
1485 { "\t ", CTimeSpan() },
1486 { "1s", CTimeSpan(0, 0, 0, 1) },
1487 { "44s", CTimeSpan(0, 0, 0, 44) },
1488 { "35m", CTimeSpan(0, 0, 35, 0) },
1489 { "1d 13h 35m 44s", CTimeSpan(1, 13, 35, 44) },
1490 { "1d13h35m44s", CTimeSpan(1, 13, 35, 44) },
1491 { "13h 35m 44s", CTimeSpan(0, 13, 35, 44) },
1492 { "35m 44s", CTimeSpan(0, 0, 35, 44) },
1493 { "1d 13h 35m", CTimeSpan(1, 13, 35, 0) },
1494 { "13h 35m", CTimeSpan(0, 13, 35, 0) },
1495 { "1d 44s", CTimeSpan(1, 0, 0, 44) },
1496 { "1d 13h", CTimeSpan(1, 13, 0, 0) },
1497 { "1d 35m 44s", CTimeSpan(1, 0, 35, 44) },
1498 { "1 day 35m 3.4s", CTimeSpan(1, 0, 35, 3, 400000000) },
1499 { "1d 35m 44s 3ms", CTimeSpan(1, 0, 35, 44, 3000000) },
1500 { "2mo 13h", CTimeSpan(2*(long)kAverageSecondsPerMonth + 13*3600L, 0) },
1501 { "2y 1 nanosecond", CTimeSpan(2*(long)kAverageSecondsPerYear, 1) },
1502
1503 // fractional values
1504 { "0.2ns", CTimeSpan(0, 0, 0, 0, 0) }, // fraction of ns - rounding
1505 { "1.2ns", CTimeSpan(0, 0, 0, 0, 1) }, // fraction of ns - rounding
1506 { "1.6ns", CTimeSpan(0, 0, 0, 0, 2) }, // fraction of ns - rounding
1507 { "1.2ms", CTimeSpan(0, 0, 0, 0, 1200000) },
1508 { "1.2us", CTimeSpan(0, 0, 0, 0, 1200) },
1509 { "1.2s", CTimeSpan(0, 0, 0, 1, 200000000) },
1510 { "1.003s", CTimeSpan(0, 0, 0, 1, 3000000) },
1511 { "1.000004s", CTimeSpan(0, 0, 0, 1, 4000) },
1512 { "1.000000005s", CTimeSpan(0, 0, 0, 1, 5) },
1513 { "0.000000001s", CTimeSpan(0, 0, 0, 0, 1) },
1514 { "1.s", CTimeSpan(0, 0, 0, 1) },
1515 { "1.5m", CTimeSpan(0, 0, 0, 90) },
1516 { "1.2h", CTimeSpan(0, 1, 12, 0) },
1517 { "1.25h", CTimeSpan(0, 1, 15, 0) },
1518 { "2.3d", CTimeSpan( 2, 7, 12, 0) }, // 24*2 + 7.2 hours
1519 { "1.2mo", CTimeSpan((long)kAverageSecondsPerMonth*12/10) },
1520 { "1.5mo 1.8d", CTimeSpan((long)kAverageSecondsPerMonth*15/10 + 43*3600L + 12*60L) }, // 1.8d = 1d + 19.2h = 43h 12m
1521 { "1.2y", CTimeSpan((long)kAverageSecondsPerYear*12/10) },
1522 { "2.3y", CTimeSpan((long)kAverageSecondsPerYear*23/10) },
1523 { "1y 3.2s", CTimeSpan((long)kAverageSecondsPerYear + 3, 200000000) },
1524 { " 1y3.2s ", CTimeSpan((long)kAverageSecondsPerYear + 3, 200000000) },
1525
1526 // stopper
1527 { NULL, CTimeSpan() }
1528 };
1529
1530 CTimeSpan ts;
1531
1532 for (int i = 0; s_Test[i].str; i++) {
1533 ts.AssignFromSmartString(s_Test[i].str);
1534 #if 1
1535 assert(ts == s_Test[i].result);
1536 #else
1537 if (ts != s_Test[i].result) {
1538 cout << i << ". " << s_Test[i].str << " != " << s_Test[i].result.AsString() << endl;
1539 }
1540 #endif
1541 }
1542
1543 // Tests that throw exceptions
1544 static const STest s_Test_Ex[] = {
1545 { "1", CTimeSpan() }, // no time specifier
1546 { "s", CTimeSpan() }, // no value
1547 { "2k", CTimeSpan() }, // unknown specifier
1548 { "1d 2d", CTimeSpan() }, // repetitions not allowed
1549 { "1day 2d", CTimeSpan() }, // repetitions not allowed
1550 { "1.2s 3ns", CTimeSpan() }, // implicit repetitions not allowed
1551 { "1..2s", CTimeSpan() }, // double ..
1552 // stopper
1553 { NULL, CTimeSpan() }
1554 };
1555 for (int i = 0; s_Test_Ex[i].str; i++) {
1556 try {
1557 ts.AssignFromSmartString(s_Test_Ex[i].str);
1558 _TROUBLE;
1559 }
1560 catch (CTimeException&) {}
1561 }
1562 }
1563
1564
1565
1566 //============================================================================
1567 //
1568 // TestTimeSpan -- AsSmartString()
1569 //
1570 //============================================================================
1571
s_TestTimeSpan_AsSmartString(void)1572 static void s_TestTimeSpan_AsSmartString(void)
1573 {
1574 typedef CTimeSpan TS;
1575 struct STest {
1576 TS timespan;
1577 TS::TSmartStringFlags flags;
1578 const char* res_full;
1579 const char* res_short;
1580 };
1581
1582 // Shorten some common flags combinations
1583 TS::TSmartStringFlags fTN = TS::fSS_Trunc | TS::fSS_NoSkipZero;
1584 TS::TSmartStringFlags fTS = TS::fSS_Trunc | TS::fSS_SkipZero;
1585 TS::TSmartStringFlags fRN = TS::fSS_Round | TS::fSS_NoSkipZero;
1586 TS::TSmartStringFlags fRS = TS::fSS_Round | TS::fSS_SkipZero;
1587
1588 static const STest s_Test[] = {
1589
1590 // Smart mode for timespans < 1 min (CXX-4101)
1591 { TS( 0, 0), fTS, "0 seconds", "0s" },
1592 { TS( 1, 0), fTS, "1 second", "1s" },
1593 { TS( 1, 1000000), fTS, "1 second", "1s" },
1594 { TS( 0, 999), fTS, "999 nanoseconds", "999ns" },
1595 { TS( 0, 1000), fTS, "1 microsecond", "1us" },
1596 { TS( 0, 1000000), fTS, "1 millisecond", "1ms" },
1597 { TS( 0, 100000000), fTS, "100 milliseconds", "100ms" },
1598 { TS( 0, 1000000001), fTS, "1 second", "1s" },
1599 { TS(59, 900000000), fTS, "59.9 seconds", "59.9s" },
1600 { TS(12, 41000000), fTS, "12 seconds", "12s" },
1601 { TS(12, 341000000), fTS, "12.3 seconds", "12.3s" },
1602 { TS( 1, 234100000), fTS, "1.23 seconds", "1.23s" },
1603 { TS( 0, 123410000), fTS, "123 milliseconds", "123ms" },
1604 { TS( 0, 12341000), fTS, "12.3 milliseconds", "12.3ms" },
1605 { TS( 0, 1234100), fTS, "1.23 milliseconds", "1.23ms" },
1606 { TS( 0, 123410), fTS, "123 microseconds", "123us" },
1607 { TS( 0, 12341), fTS, "12.3 microseconds", "12.3us" },
1608 { TS( 0, 1234), fTS, "1.23 microseconds", "1.23us" },
1609 { TS( 0, 123), fTS, "123 nanoseconds", "123ns" },
1610 { TS( 0, 12), fTS, "12 nanoseconds", "12ns" },
1611 { TS( 0, 999000000), fTS, "999 milliseconds", "999ms" },
1612 { TS( 0, 999500000), fTS, "999 milliseconds", "999ms" },
1613 { TS( 0, 999000), fTS, "999 microseconds", "999us" },
1614 { TS( 0, 999500), fTS, "999 microseconds", "999us" },
1615
1616 { TS( 0, 0), fRS, "0 seconds", "0s" },
1617 { TS( 1, 0), fRS, "1 second", "1s" },
1618 { TS( 1, 1000000), fRS, "1 second", "1s" },
1619 { TS( 0, 999), fRS, "999 nanoseconds", "999ns" },
1620 { TS( 0, 1000), fRS, "1 microsecond", "1us" },
1621 { TS( 0, 1000000), fRS, "1 millisecond", "1ms" },
1622 { TS( 0, 100000000), fRS, "100 milliseconds", "100ms" },
1623 { TS( 0, 1000000001), fRS, "1 second", "1s" },
1624 { TS(59, 940000000), fRS, "59.9 seconds", "59.9s" },
1625 { TS(59, 950000000), fRS, "1 minute", "1m" },
1626 { TS(12, 50000000), fRS, "12.1 seconds", "12.1s" },
1627 { TS(12, 341000000), fRS, "12.3 seconds", "12.3s" },
1628 { TS(12, 351000000), fRS, "12.4 seconds", "12.4s" },
1629 { TS( 1, 234100000), fRS, "1.23 seconds", "1.23s" },
1630 { TS( 1, 235100000), fRS, "1.24 seconds", "1.24s" },
1631 { TS( 0, 123410000), fRS, "123 milliseconds", "123ms" },
1632 { TS( 0, 123510000), fRS, "124 milliseconds", "124ms" },
1633 { TS( 0, 12341000), fRS, "12.3 milliseconds", "12.3ms" },
1634 { TS( 0, 1234100), fRS, "1.23 milliseconds", "1.23ms" },
1635 { TS( 0, 123410), fRS, "123 microseconds", "123us" },
1636 { TS( 0, 12341), fRS, "12.3 microseconds", "12.3us" },
1637 { TS( 0, 1234), fRS, "1.23 microseconds", "1.23us" },
1638 { TS( 0, 123), fRS, "123 nanoseconds", "123ns" },
1639 { TS( 0, 12), fRS, "12 nanoseconds", "12ns" },
1640 { TS( 0, 999000000), fRS, "999 milliseconds", "999ms" },
1641 { TS( 0, 999500000), fRS, "1 second", "1s" },
1642 { TS( 0, 999000), fRS, "999 microseconds", "999us" },
1643 { TS( 0, 999500), fRS, "1 millisecond", "1ms" },
1644
1645 // Smart mode for timespans >= 1 min
1646 { TS( 60, 0), fTS, "1 minute", "1m" },
1647 { TS( 61, 0), fTS, "1 minute 1 second", "1m 1s" },
1648 { TS( 119, 900000000), fTS, "1 minute 59 seconds", "1m 59s" },
1649 { TS( 600, 0), fTS, "10 minutes", "10m" },
1650 { TS( 629, 0), fTS, "10 minutes 29 seconds", "10m 29s" },
1651 { TS( 3599, 900000000), fTS, "59 minutes 59 seconds", "59m 59s" },
1652 { TS( 3600, 0), fTS, "1 hour", "1h" },
1653 { TS(36000, 0), fTS, "10 hours", "10h" },
1654 { TS(36059, 0), fTS, "10 hours", "10h" },
1655 { TS(86400, 0), fTS, "1 day", "1d" },
1656
1657 { TS( 60, 0), fRS, "1 minute", "1m" },
1658 { TS( 61, 0), fRS, "1 minute 1 second", "1m 1s" },
1659 { TS( 119, 900000000), fRS, "2 minutes", "2m" },
1660 { TS( 600, 0), fRS, "10 minutes", "10m" },
1661 { TS( 629, 0), fRS, "10 minutes 29 seconds", "10m 29s" },
1662 { TS( 3599, 900000000), fRS, "1 hour", "1h" },
1663 { TS( 3600, 0), fRS, "1 hour", "1h" },
1664 { TS(36000, 0), fRS, "10 hours", "10h" },
1665 { TS(36059, 0), fRS, "10 hours 1 minute", "10h 1m" },
1666 { TS(86400, 0), fRS, "1 day", "1d" },
1667
1668 { TS(29,23,59,1,0), fTS, "29 days 23 hours", "29d 23h" },
1669 { TS(29,23,59,1,0), fRS, "30 days", "30d" },
1670 { TS((long)kAverageSecondsPerMonth-1), fTS, "30 days 10 hours", "30d 10h" },
1671 { TS((long)kAverageSecondsPerMonth-1), fRS, "1 month", "1mo" },
1672 { TS((long)kAverageSecondsPerMonth), fTS, "1 month", "1mo" },
1673 { TS((long)kAverageSecondsPerMonth), fRS, "1 month", "1mo" },
1674 { TS((long)kAverageSecondsPerMonth+1), fTS, "1 month", "1mo" },
1675 { TS((long)kAverageSecondsPerMonth+1), fRS, "1 month", "1mo" },
1676 { TS(559,0,59,41,900500), fTS, "1 year 6 months", "1y 6mo" },
1677 { TS(559,0,59,41,900500), fRS, "1 year 6 months", "1y 6mo" },
1678
1679
1680 // zero time span
1681 { TS(0,0), fTN | TS::fSS_Year, "0 years", "0y" },
1682 { TS(0,0), fTN | TS::fSS_Month, "0 months", "0mo" },
1683 { TS(0,0), fTN | TS::fSS_Day, "0 days", "0d" },
1684 { TS(0,0), fTN | TS::fSS_Minute, "0 minutes", "0m" },
1685 { TS(0,0), fTN | TS::fSS_Second, "0 seconds", "0s" },
1686 { TS(0,0), fTN | TS::fSS_Millisecond, "0 seconds", "0s" },
1687 { TS(0,0), fTN | TS::fSS_Microsecond, "0 seconds", "0s" },
1688 { TS(0,0), fTN | TS::fSS_Nanosecond, "0 seconds", "0s" },
1689 { TS(0,0), fTN | TS::fSS_Precision1, "0 seconds", "0s" },
1690 { TS(0,0), fTN | TS::fSS_Precision2, "0 seconds", "0s" },
1691 { TS(0,0), fTN | TS::fSS_Precision3, "0 seconds", "0s" },
1692 { TS(0,0), fTN | TS::fSS_Precision4, "0 seconds", "0s" },
1693 { TS(0,0), fTN | TS::fSS_Precision5, "0 seconds", "0s" },
1694 { TS(0,0), fTN | TS::fSS_Precision6, "0 seconds", "0s" },
1695 { TS(0,0), fTN | TS::fSS_Precision7, "0 seconds", "0s" },
1696 { TS(0,0), fTS | TS::fSS_Year, "0 years", "0y" },
1697 { TS(0,0), fTS | TS::fSS_Month, "0 months", "0mo" },
1698 { TS(0,0), fTS | TS::fSS_Day, "0 days", "0d" },
1699 { TS(0,0), fTS | TS::fSS_Minute, "0 minutes", "0m" },
1700 { TS(0,0), fTS | TS::fSS_Second, "0 seconds", "0s" },
1701 { TS(0,0), fTS | TS::fSS_Millisecond, "0 seconds", "0s" },
1702 { TS(0,0), fTS | TS::fSS_Microsecond, "0 seconds", "0s" },
1703 { TS(0,0), fTS | TS::fSS_Nanosecond, "0 seconds", "0s" },
1704 { TS(0,0), fTS | TS::fSS_Precision1, "0 seconds", "0s" },
1705 { TS(0,0), fTS | TS::fSS_Precision2, "0 seconds", "0s" },
1706 { TS(0,0), fTS | TS::fSS_Precision3, "0 seconds", "0s" },
1707 { TS(0,0), fTS | TS::fSS_Precision4, "0 seconds", "0s" },
1708 { TS(0,0), fTS | TS::fSS_Precision5, "0 seconds", "0s" },
1709 { TS(0,0), fTS | TS::fSS_Precision6, "0 seconds", "0s" },
1710 { TS(0,0), fTS | TS::fSS_Precision7, "0 seconds", "0s" },
1711
1712 // 1 second
1713 { TS(1,0), fTN | TS::fSS_Year, "0 years", "0y" },
1714 { TS(1,0), fTN | TS::fSS_Month, "0 months", "0mo" },
1715 { TS(1,0), fTN | TS::fSS_Day, "0 days", "0d" },
1716 { TS(1,0), fTN | TS::fSS_Minute, "0 minutes", "0m" },
1717 { TS(1,0), fTN | TS::fSS_Second, "1 second", "1s" },
1718 { TS(1,0), fTN | TS::fSS_Millisecond, "1 second", "1s" },
1719 { TS(1,0), fTN | TS::fSS_Microsecond, "1 second", "1s" },
1720 { TS(1,0), fTN | TS::fSS_Nanosecond, "1 second", "1s" },
1721 { TS(1,0), fTN | TS::fSS_Precision1, "1 second", "1s" },
1722 { TS(1,0), fTN | TS::fSS_Precision2, "1 second", "1s" },
1723 { TS(1,0), fTN | TS::fSS_Precision3, "1 second", "1s" },
1724 { TS(1,0), fTN | TS::fSS_Precision4, "1 second", "1s" },
1725 { TS(1,0), fTN | TS::fSS_Precision5, "1 second", "1s" },
1726 { TS(1,0), fTN | TS::fSS_Precision6, "1 second", "1s" },
1727 { TS(1,0), fTN | TS::fSS_Precision7, "1 second", "1s" },
1728 { TS(1,0), fTN | TS::fSS_Year, "0 years", "0y" },
1729 { TS(1,0), fTS | TS::fSS_Month, "0 months", "0mo" },
1730 { TS(1,0), fTS | TS::fSS_Day, "0 days", "0d" },
1731 { TS(1,0), fTS | TS::fSS_Minute, "0 minutes", "0m" },
1732 { TS(1,0), fTS | TS::fSS_Second, "1 second", "1s" },
1733 { TS(1,0), fTS | TS::fSS_Millisecond, "1 second", "1s" },
1734 { TS(1,0), fTS | TS::fSS_Microsecond, "1 second", "1s" },
1735 { TS(1,0), fTS | TS::fSS_Nanosecond, "1 second", "1s" },
1736 { TS(1,0), fTS | TS::fSS_Precision1, "1 second", "1s" },
1737 { TS(1,0), fTS | TS::fSS_Precision2, "1 second", "1s" },
1738 { TS(1,0), fTS | TS::fSS_Precision3, "1 second", "1s" },
1739 { TS(1,0), fTS | TS::fSS_Precision4, "1 second", "1s" },
1740 { TS(1,0), fTS | TS::fSS_Precision5, "1 second", "1s" },
1741 { TS(1,0), fTS | TS::fSS_Precision6, "1 second", "1s" },
1742 { TS(1,0), fTS | TS::fSS_Precision7, "1 second", "1s" },
1743
1744 // 1 second 1 millisecond
1745 { TS(1,1000000), fTN | TS::fSS_Year, "0 years", "0y" },
1746 { TS(1,1000000), fTN | TS::fSS_Month, "0 months", "0mo" },
1747 { TS(1,1000000), fTN | TS::fSS_Day, "0 days", "0d" },
1748 { TS(1,1000000), fTN | TS::fSS_Minute, "0 minutes", "0m" },
1749 { TS(1,1000000), fTN | TS::fSS_Second, "1 second", "1s" },
1750 { TS(1,1000000), fTN | TS::fSS_Millisecond, "1 second 1 millisecond", "1s 1ms" },
1751 { TS(1,1000000), fTN | TS::fSS_Microsecond, "1 second 1000 microseconds", "1s 1000us" },
1752 { TS(1,1000000), fTN | TS::fSS_Nanosecond, "1 second 1000000 nanoseconds", "1s 1000000ns" },
1753 { TS(1,1000000), fTN | TS::fSS_Precision1, "1 second", "1s" },
1754 { TS(1,1000000), fTN | TS::fSS_Precision2, "1 second", "1s" },
1755 { TS(1,1000000), fTN | TS::fSS_Precision3, "1 second", "1s" },
1756 { TS(1,1000000), fTN | TS::fSS_Precision4, "1 second", "1s" },
1757 { TS(1,1000000), fTN | TS::fSS_Precision5, "1 second", "1s" },
1758 { TS(1,1000000), fTN | TS::fSS_Precision6, "1 second", "1s" },
1759 { TS(1,1000000), fTN | TS::fSS_Precision7, "1 second", "1s" },
1760 { TS(1,1000000), fTS | TS::fSS_Year, "0 years", "0y" },
1761 { TS(1,1000000), fTS | TS::fSS_Month, "0 months", "0mo" },
1762 { TS(1,1000000), fTS | TS::fSS_Day, "0 days", "0d" },
1763 { TS(1,1000000), fTS | TS::fSS_Minute, "0 minutes", "0m" },
1764 { TS(1,1000000), fTS | TS::fSS_Second, "1 second", "1s" },
1765 { TS(1,1000000), fTS | TS::fSS_Millisecond, "1 second 1 millisecond", "1s 1ms" },
1766 { TS(1,1000000), fTS | TS::fSS_Microsecond, "1 second 1000 microseconds", "1s 1000us" },
1767 { TS(1,1000000), fTS | TS::fSS_Nanosecond, "1 second 1000000 nanoseconds", "1s 1000000ns" },
1768 { TS(1,1000000), fTS | TS::fSS_Precision1, "1 second", "1s" },
1769 { TS(1,1000000), fTS | TS::fSS_Precision2, "1 second", "1s" },
1770 { TS(1,1000000), fTS | TS::fSS_Precision3, "1 second", "1s" },
1771 { TS(1,1000000), fTS | TS::fSS_Precision4, "1 second", "1s" },
1772 { TS(1,1000000), fTS | TS::fSS_Precision5, "1 second", "1s" },
1773 { TS(1,1000000), fTS | TS::fSS_Precision6, "1 second", "1s" },
1774 { TS(1,1000000), fTS | TS::fSS_Precision7, "1 second", "1s" },
1775
1776 // 1 minute 1 second
1777 { TS(61,0), fTN | TS::fSS_Year, "0 years", "0y" },
1778 { TS(61,0), fTN | TS::fSS_Month, "0 months", "0mo" },
1779 { TS(61,0), fTN | TS::fSS_Day, "0 days", "0d" },
1780 { TS(61,0), fTN | TS::fSS_Minute, "1 minute", "1m" },
1781 { TS(61,0), fTN | TS::fSS_Second, "1 minute 1 second", "1m 1s" },
1782 { TS(61,0), fTN | TS::fSS_Millisecond, "1 minute 1 second", "1m 1s" },
1783 { TS(61,0), fTN | TS::fSS_Microsecond, "1 minute 1 second", "1m 1s" },
1784 { TS(61,0), fTN | TS::fSS_Nanosecond, "1 minute 1 second", "1m 1s" },
1785 { TS(61,0), fTN | TS::fSS_Precision1, "1 minute", "1m" },
1786 { TS(61,0), fTN | TS::fSS_Precision2, "1 minute 1 second", "1m 1s" },
1787 { TS(61,0), fTN | TS::fSS_Precision3, "1 minute 1 second", "1m 1s" },
1788 { TS(61,0), fTN | TS::fSS_Precision4, "1 minute 1 second", "1m 1s" },
1789 { TS(61,0), fTN | TS::fSS_Precision5, "1 minute 1 second", "1m 1s" },
1790 { TS(61,0), fTN | TS::fSS_Precision6, "1 minute 1 second", "1m 1s" },
1791 { TS(61,0), fTN | TS::fSS_Precision7, "1 minute 1 second", "1m 1s" },
1792 { TS(61,0), fTS | TS::fSS_Year, "0 years", "0y" },
1793 { TS(61,0), fTS | TS::fSS_Month, "0 months", "0mo" },
1794 { TS(61,0), fTS | TS::fSS_Day, "0 days", "0d" },
1795 { TS(61,0), fTS | TS::fSS_Minute, "1 minute", "1m" },
1796 { TS(61,0), fTS | TS::fSS_Second, "1 minute 1 second", "1m 1s" },
1797 { TS(61,0), fTS | TS::fSS_Millisecond, "1 minute 1 second", "1m 1s" },
1798 { TS(61,0), fTS | TS::fSS_Microsecond, "1 minute 1 second", "1m 1s" },
1799 { TS(61,0), fTS | TS::fSS_Nanosecond, "1 minute 1 second", "1m 1s" },
1800 { TS(61,0), fTS | TS::fSS_Precision1, "1 minute", "1m" },
1801 { TS(61,0), fTS | TS::fSS_Precision2, "1 minute 1 second", "1m 1s" },
1802 { TS(61,0), fTS | TS::fSS_Precision3, "1 minute 1 second", "1m 1s" },
1803 { TS(61,0), fTS | TS::fSS_Precision4, "1 minute 1 second", "1m 1s" },
1804 { TS(61,0), fTS | TS::fSS_Precision5, "1 minute 1 second", "1m 1s" },
1805 { TS(61,0), fTS | TS::fSS_Precision6, "1 minute 1 second", "1m 1s" },
1806 { TS(61,0), fTS | TS::fSS_Precision7, "1 minute 1 second", "1m 1s" },
1807
1808 // 999 nanoseconds
1809 { TS(0,999), fTS | TS::fSS_Year, "0 years", "0y" },
1810 { TS(0,999), fTS | TS::fSS_Month, "0 months", "0mo" },
1811 { TS(0,999), fTS | TS::fSS_Day, "0 days", "0d" },
1812 { TS(0,999), fTS | TS::fSS_Minute, "0 minutes", "0m" },
1813 { TS(0,999), fTS | TS::fSS_Second, "0 seconds", "0s" },
1814 { TS(0,999), fTS | TS::fSS_Millisecond, "0 seconds", "0s" },
1815 { TS(0,999), fTS | TS::fSS_Microsecond, "0 seconds", "0s" },
1816 { TS(0,999), fTS | TS::fSS_Nanosecond, "999 nanoseconds", "999ns" },
1817 { TS(0,999), fRS | TS::fSS_Millisecond, "0 seconds", "0s" },
1818 { TS(0,999), fRS | TS::fSS_Microsecond, "1 microsecond", "1us" },
1819 { TS(0,999), fRS | TS::fSS_Nanosecond, "999 nanoseconds", "999ns" },
1820
1821 // 1000 nanoseconds
1822 { TS(0,1000), fTS | TS::fSS_Year, "0 years", "0y" },
1823 { TS(0,1000), fTS | TS::fSS_Month, "0 months", "0mo" },
1824 { TS(0,1000), fTS | TS::fSS_Day, "0 days", "0d" },
1825 { TS(0,1000), fTS | TS::fSS_Minute, "0 minutes", "0m" },
1826 { TS(0,1000), fTS | TS::fSS_Second, "0 seconds", "0s" },
1827 { TS(0,1000), fTS | TS::fSS_Millisecond, "0 seconds", "0s" },
1828 { TS(0,1000), fTS | TS::fSS_Microsecond, "1 microsecond", "1us" },
1829 { TS(0,1000), fTS | TS::fSS_Nanosecond, "1000 nanoseconds", "1000ns" },
1830
1831 // 1,000,000 nanoseconds
1832 { TS(0,1000000), fTS | TS::fSS_Year, "0 years", "0y" },
1833 { TS(0,1000000), fTS | TS::fSS_Month, "0 months", "0mo" },
1834 { TS(0,1000000), fTS | TS::fSS_Day, "0 days", "0d" },
1835 { TS(0,1000000), fTS | TS::fSS_Minute, "0 minutes", "0m" },
1836 { TS(0,1000000), fTS | TS::fSS_Second, "0 seconds", "0s" },
1837 { TS(0,1000000), fTS | TS::fSS_Millisecond, "1 millisecond", "1ms" },
1838 { TS(0,1000000), fTS | TS::fSS_Microsecond, "1000 microseconds", "1000us" },
1839 { TS(0,1000000), fTS | TS::fSS_Nanosecond, "1000000 nanoseconds", "1000000ns" },
1840
1841 // 100,000,000 nanoseconds
1842 { TS(0,100000000), fTS | TS::fSS_Year, "0 years", "0y" },
1843 { TS(0,100000000), fTS | TS::fSS_Month, "0 months", "0mo" },
1844 { TS(0,100000000), fTS | TS::fSS_Day, "0 days", "0d" },
1845 { TS(0,100000000), fTS | TS::fSS_Minute, "0 minutes", "0m" },
1846 { TS(0,100000000), fTS | TS::fSS_Second, "0 seconds", "0s" },
1847 { TS(0,100000000), fTS | TS::fSS_Millisecond, "100 milliseconds", "100ms" },
1848 { TS(0,100000000), fTS | TS::fSS_Microsecond, "100000 microseconds", "100000us" },
1849 { TS(0,100000000), fTS | TS::fSS_Nanosecond, "100000000 nanoseconds", "100000000ns" },
1850
1851 // 1,000,000,000 nanoseconds
1852 { TS(0,1000000000), fTN | TS::fSS_Millisecond, "1 second", "1s" },
1853 { TS(0,1000000000), fTN | TS::fSS_Microsecond, "1 second", "1s" },
1854 { TS(0,1000000000), fTN | TS::fSS_Nanosecond, "1 second", "1s" },
1855 { TS(0,1000000000), fTS | TS::fSS_Year, "0 years", "0y" },
1856 { TS(0,1000000000), fTS | TS::fSS_Month, "0 months", "0mo" },
1857 { TS(0,1000000000), fTS | TS::fSS_Day, "0 days", "0d" },
1858 { TS(0,1000000000), fTS | TS::fSS_Minute, "0 minutes", "0m" },
1859 { TS(0,1000000000), fTS | TS::fSS_Second, "1 second", "1s" },
1860 { TS(0,1000000000), fTS | TS::fSS_Millisecond, "1 second", "1s" },
1861 { TS(0,1000000000), fTS | TS::fSS_Microsecond, "1 second", "1s" },
1862 { TS(0,1000000000), fTS | TS::fSS_Nanosecond, "1 second", "1s" },
1863
1864 // 1,000,000,001 nanoseconds
1865 { TS(0,1000000001), fTN | TS::fSS_Second, "1 second", "1s" },
1866 { TS(0,1000000001), fTN | TS::fSS_Millisecond, "1 second", "1s" },
1867 { TS(0,1000000001), fTN | TS::fSS_Microsecond, "1 second", "1s" },
1868 { TS(0,1000000001), fTN | TS::fSS_Nanosecond, "1 second 1 nanosecond", "1s 1ns" },
1869 { TS(0,1000000001), fTS | TS::fSS_Year, "0 years", "0y" },
1870 { TS(0,1000000001), fTS | TS::fSS_Month, "0 months", "0mo" },
1871 { TS(0,1000000001), fTS | TS::fSS_Day, "0 days", "0d" },
1872 { TS(0,1000000001), fTS | TS::fSS_Minute, "0 minutes", "0m" },
1873 { TS(0,1000000001), fTS | TS::fSS_Second, "1 second", "1s" },
1874 { TS(0,1000000001), fTS | TS::fSS_Millisecond, "1 second", "1s" },
1875 { TS(0,1000000001), fTS | TS::fSS_Microsecond, "1 second", "1s" },
1876 { TS(0,1000000001), fTS | TS::fSS_Nanosecond, "1 second 1 nanosecond", "1s 1ns" },
1877
1878 #if (SIZEOF_LONG == 8)
1879 // 10,000,000,000 nanoseconds
1880 { TS(0,NCBI_CONST_INT8(10000000000)), fTS | TS::fSS_Smart, "10 seconds", "10s" },
1881 { TS(0,NCBI_CONST_INT8(10000000000)), fTS | TS::fSS_Year, "0 years", "0y" },
1882 { TS(0,NCBI_CONST_INT8(10000000000)), fTS | TS::fSS_Month, "0 months", "0mo" },
1883 { TS(0,NCBI_CONST_INT8(10000000000)), fTS | TS::fSS_Day, "0 days", "0d" },
1884 { TS(0,NCBI_CONST_INT8(10000000000)), fTS | TS::fSS_Minute, "0 minutes", "0m" },
1885 { TS(0,NCBI_CONST_INT8(10000000000)), fTS | TS::fSS_Second, "10 seconds", "10s" },
1886 { TS(0,NCBI_CONST_INT8(10000000000)), fTS | TS::fSS_Millisecond, "10 seconds", "10s" },
1887 { TS(0,NCBI_CONST_INT8(10000000000)), fTS | TS::fSS_Microsecond, "10 seconds", "10s" },
1888 { TS(0,NCBI_CONST_INT8(10000000000)), fTS | TS::fSS_Nanosecond, "10 seconds", "10s" },
1889 #endif
1890
1891 // 60 second
1892 { TS(60,0), fTN | TS::fSS_Year, "0 years", "0y" },
1893 { TS(60,0), fTN | TS::fSS_Month, "0 months", "0mo" },
1894 { TS(60,0), fTN | TS::fSS_Day, "0 days", "0d" },
1895 { TS(60,0), fTN | TS::fSS_Minute, "1 minute", "1m" },
1896 { TS(60,0), fTN | TS::fSS_Second, "1 minute", "1m" },
1897 { TS(60,0), fTN | TS::fSS_Millisecond, "1 minute", "1m" },
1898 { TS(60,0), fTN | TS::fSS_Microsecond, "1 minute", "1m" },
1899 { TS(60,0), fTN | TS::fSS_Nanosecond, "1 minute", "1m" },
1900 { TS(60,0), fTN | TS::fSS_Precision1, "1 minute", "1m" },
1901 { TS(60,0), fTN | TS::fSS_Precision2, "1 minute", "1m" },
1902 { TS(60,0), fTN | TS::fSS_Precision3, "1 minute", "1m" },
1903 { TS(60,0), fTN | TS::fSS_Precision4, "1 minute", "1m" },
1904 { TS(60,0), fTN | TS::fSS_Precision5, "1 minute", "1m" },
1905 { TS(60,0), fTN | TS::fSS_Precision6, "1 minute", "1m" },
1906 { TS(60,0), fTN | TS::fSS_Precision7, "1 minute", "1m" },
1907 { TS(60,0), fTS | TS::fSS_Year, "0 years", "0y" },
1908 { TS(60,0), fTS | TS::fSS_Month, "0 months", "0mo" },
1909 { TS(60,0), fTS | TS::fSS_Day, "0 days", "0d" },
1910 { TS(60,0), fTS | TS::fSS_Minute, "1 minute", "1m" },
1911 { TS(60,0), fTS | TS::fSS_Second, "1 minute", "1m" },
1912 { TS(60,0), fTS | TS::fSS_Millisecond, "1 minute", "1m" },
1913 { TS(60,0), fTS | TS::fSS_Microsecond, "1 minute", "1m" },
1914 { TS(60,0), fTS | TS::fSS_Nanosecond, "1 minute", "1m" },
1915 { TS(60,0), fTS | TS::fSS_Precision1, "1 minute", "1m" },
1916 { TS(60,0), fTS | TS::fSS_Precision2, "1 minute", "1m" },
1917 { TS(60,0), fTS | TS::fSS_Precision3, "1 minute", "1m" },
1918 { TS(60,0), fTS | TS::fSS_Precision4, "1 minute", "1m" },
1919 { TS(60,0), fTS | TS::fSS_Precision5, "1 minute", "1m" },
1920 { TS(60,0), fTS | TS::fSS_Precision6, "1 minute", "1m" },
1921 { TS(60,0), fTS | TS::fSS_Precision7, "1 minute", "1m" },
1922
1923 // 600 seconds
1924 { TS(600,0), fTN | TS::fSS_Year, "0 years", "0y" },
1925 { TS(600,0), fTN | TS::fSS_Month, "0 months", "0mo" },
1926 { TS(600,0), fTN | TS::fSS_Day, "0 days", "0d" },
1927 { TS(600,0), fTN | TS::fSS_Minute, "10 minutes", "10m" },
1928 { TS(600,0), fTN | TS::fSS_Second, "10 minutes", "10m" },
1929 { TS(600,0), fTN | TS::fSS_Millisecond, "10 minutes", "10m" },
1930 { TS(600,0), fTN | TS::fSS_Microsecond, "10 minutes", "10m" },
1931 { TS(600,0), fTN | TS::fSS_Nanosecond, "10 minutes", "10m" },
1932 { TS(600,0), fTN | TS::fSS_Precision1, "10 minutes", "10m" },
1933 { TS(600,0), fTN | TS::fSS_Precision2, "10 minutes", "10m" },
1934 { TS(600,0), fTN | TS::fSS_Precision3, "10 minutes", "10m" },
1935 { TS(600,0), fTN | TS::fSS_Precision4, "10 minutes", "10m" },
1936 { TS(600,0), fTN | TS::fSS_Precision5, "10 minutes", "10m" },
1937 { TS(600,0), fTN | TS::fSS_Precision6, "10 minutes", "10m" },
1938 { TS(600,0), fTN | TS::fSS_Precision7, "10 minutes", "10m" },
1939 { TS(600,0), fTS | TS::fSS_Year, "0 years", "0y" },
1940 { TS(600,0), fTS | TS::fSS_Month, "0 months", "0mo" },
1941 { TS(600,0), fTS | TS::fSS_Day, "0 days", "0d" },
1942 { TS(600,0), fTS | TS::fSS_Minute, "10 minutes", "10m" },
1943 { TS(600,0), fTS | TS::fSS_Second, "10 minutes", "10m" },
1944 { TS(600,0), fTS | TS::fSS_Millisecond, "10 minutes", "10m" },
1945 { TS(600,0), fTS | TS::fSS_Microsecond, "10 minutes", "10m" },
1946 { TS(600,0), fTS | TS::fSS_Nanosecond, "10 minutes", "10m" },
1947 { TS(600,0), fTS | TS::fSS_Precision1, "10 minutes", "10m" },
1948 { TS(600,0), fTS | TS::fSS_Precision2, "10 minutes", "10m" },
1949 { TS(600,0), fTS | TS::fSS_Precision3, "10 minutes", "10m" },
1950 { TS(600,0), fTS | TS::fSS_Precision4, "10 minutes", "10m" },
1951 { TS(600,0), fTS | TS::fSS_Precision5, "10 minutes", "10m" },
1952 { TS(600,0), fTS | TS::fSS_Precision6, "10 minutes", "10m" },
1953 { TS(600,0), fTS | TS::fSS_Precision7, "10 minutes", "10m" },
1954
1955 // 3600 seconds
1956 { TS(3600,0), fTN | TS::fSS_Year, "0 years", "0y" },
1957 { TS(3600,0), fTN | TS::fSS_Month, "0 months", "0mo" },
1958 { TS(3600,0), fTN | TS::fSS_Day, "0 days", "0d" },
1959 { TS(3600,0), fTN | TS::fSS_Minute, "1 hour", "1h" },
1960 { TS(3600,0), fTN | TS::fSS_Second, "1 hour", "1h" },
1961 { TS(3600,0), fTN | TS::fSS_Millisecond, "1 hour", "1h" },
1962 { TS(3600,0), fTN | TS::fSS_Microsecond, "1 hour", "1h" },
1963 { TS(3600,0), fTN | TS::fSS_Nanosecond, "1 hour", "1h" },
1964 { TS(3600,0), fTN | TS::fSS_Precision1, "1 hour", "1h" },
1965 { TS(3600,0), fTN | TS::fSS_Precision2, "1 hour", "1h" },
1966 { TS(3600,0), fTN | TS::fSS_Precision3, "1 hour", "1h" },
1967 { TS(3600,0), fTN | TS::fSS_Precision4, "1 hour", "1h" },
1968 { TS(3600,0), fTN | TS::fSS_Precision5, "1 hour", "1h" },
1969 { TS(3600,0), fTN | TS::fSS_Precision6, "1 hour", "1h" },
1970 { TS(3600,0), fTN | TS::fSS_Precision7, "1 hour", "1h" },
1971 { TS(3600,0), fTS | TS::fSS_Year, "0 years", "0y" },
1972 { TS(3600,0), fTS | TS::fSS_Month, "0 months", "0mo" },
1973 { TS(3600,0), fTS | TS::fSS_Day, "0 days", "0d" },
1974 { TS(3600,0), fTS | TS::fSS_Minute, "1 hour", "1h" },
1975 { TS(3600,0), fTS | TS::fSS_Second, "1 hour", "1h" },
1976 { TS(3600,0), fTS | TS::fSS_Millisecond, "1 hour", "1h" },
1977 { TS(3600,0), fTS | TS::fSS_Microsecond, "1 hour", "1h" },
1978 { TS(3600,0), fTS | TS::fSS_Nanosecond, "1 hour", "1h" },
1979 { TS(3600,0), fTS | TS::fSS_Precision1, "1 hour", "1h" },
1980 { TS(3600,0), fTS | TS::fSS_Precision2, "1 hour", "1h" },
1981 { TS(3600,0), fTS | TS::fSS_Precision3, "1 hour", "1h" },
1982 { TS(3600,0), fTS | TS::fSS_Precision4, "1 hour", "1h" },
1983 { TS(3600,0), fTS | TS::fSS_Precision5, "1 hour", "1h" },
1984 { TS(3600,0), fTS | TS::fSS_Precision6, "1 hour", "1h" },
1985 { TS(3600,0), fTS | TS::fSS_Precision7, "1 hour", "1h" },
1986
1987 // 36000 seconds
1988 { TS(36000,0), fTN | TS::fSS_Year, "0 years", "0y" },
1989 { TS(36000,0), fTN | TS::fSS_Month, "0 months", "0mo" },
1990 { TS(36000,0), fTN | TS::fSS_Day, "0 days", "0d" },
1991 { TS(36000,0), fTN | TS::fSS_Minute, "10 hours", "10h" },
1992 { TS(36000,0), fTN | TS::fSS_Second, "10 hours", "10h" },
1993 { TS(36000,0), fTN | TS::fSS_Millisecond, "10 hours", "10h" },
1994 { TS(36000,0), fTN | TS::fSS_Microsecond, "10 hours", "10h" },
1995 { TS(36000,0), fTN | TS::fSS_Nanosecond, "10 hours", "10h" },
1996 { TS(36000,0), fTN | TS::fSS_Precision1, "10 hours", "10h" },
1997 { TS(36000,0), fTN | TS::fSS_Precision2, "10 hours", "10h" },
1998 { TS(36000,0), fTN | TS::fSS_Precision3, "10 hours", "10h" },
1999 { TS(36000,0), fTN | TS::fSS_Precision4, "10 hours", "10h" },
2000 { TS(36000,0), fTN | TS::fSS_Precision5, "10 hours", "10h" },
2001 { TS(36000,0), fTN | TS::fSS_Precision6, "10 hours", "10h" },
2002 { TS(36000,0), fTN | TS::fSS_Precision7, "10 hours", "10h" },
2003 { TS(36000,0), fTS | TS::fSS_Year, "0 years", "0y" },
2004 { TS(36000,0), fTS | TS::fSS_Month, "0 months", "0mo" },
2005 { TS(36000,0), fTS | TS::fSS_Day, "0 days", "0d" },
2006 { TS(36000,0), fTS | TS::fSS_Minute, "10 hours", "10h" },
2007 { TS(36000,0), fTS | TS::fSS_Second, "10 hours", "10h" },
2008 { TS(36000,0), fTS | TS::fSS_Millisecond, "10 hours", "10h" },
2009 { TS(36000,0), fTS | TS::fSS_Microsecond, "10 hours", "10h" },
2010 { TS(36000,0), fTS | TS::fSS_Nanosecond, "10 hours", "10h" },
2011 { TS(36000,0), fTS | TS::fSS_Precision1, "10 hours", "10h" },
2012 { TS(36000,0), fTS | TS::fSS_Precision2, "10 hours", "10h" },
2013 { TS(36000,0), fTS | TS::fSS_Precision3, "10 hours", "10h" },
2014 { TS(36000,0), fTS | TS::fSS_Precision4, "10 hours", "10h" },
2015 { TS(36000,0), fTS | TS::fSS_Precision5, "10 hours", "10h" },
2016 { TS(36000,0), fTS | TS::fSS_Precision6, "10 hours", "10h" },
2017 { TS(36000,0), fTS | TS::fSS_Precision7, "10 hours", "10h" },
2018
2019 // 86400 seconds
2020 { TS(86400,0), fTN | TS::fSS_Year, "0 years", "0y" },
2021 { TS(86400,0), fTN | TS::fSS_Month, "0 months", "0mo" },
2022 { TS(86400,0), fTN | TS::fSS_Day, "1 day", "1d" },
2023 { TS(86400,0), fTN | TS::fSS_Minute, "1 day", "1d" },
2024 { TS(86400,0), fTN | TS::fSS_Second, "1 day", "1d" },
2025 { TS(86400,0), fTN | TS::fSS_Millisecond, "1 day", "1d" },
2026 { TS(86400,0), fTN | TS::fSS_Microsecond, "1 day", "1d" },
2027 { TS(86400,0), fTN | TS::fSS_Nanosecond, "1 day", "1d" },
2028 { TS(86400,0), fTN | TS::fSS_Precision1, "1 day", "1d" },
2029 { TS(86400,0), fTN | TS::fSS_Precision2, "1 day", "1d" },
2030 { TS(86400,0), fTN | TS::fSS_Precision3, "1 day", "1d" },
2031 { TS(86400,0), fTN | TS::fSS_Precision4, "1 day", "1d" },
2032 { TS(86400,0), fTN | TS::fSS_Precision5, "1 day", "1d" },
2033 { TS(86400,0), fTN | TS::fSS_Precision6, "1 day", "1d" },
2034 { TS(86400,0), fTN | TS::fSS_Precision7, "1 day", "1d" },
2035 { TS(86400,0), fTS | TS::fSS_Year, "0 years", "0y" },
2036 { TS(86400,0), fTS | TS::fSS_Month, "0 months", "0mo" },
2037 { TS(86400,0), fTS | TS::fSS_Day, "1 day", "1d" },
2038 { TS(86400,0), fTS | TS::fSS_Minute, "1 day", "1d" },
2039 { TS(86400,0), fTS | TS::fSS_Second, "1 day", "1d" },
2040 { TS(86400,0), fTS | TS::fSS_Millisecond, "1 day", "1d" },
2041 { TS(86400,0), fTS | TS::fSS_Microsecond, "1 day", "1d" },
2042 { TS(86400,0), fTS | TS::fSS_Nanosecond, "1 day", "1d" },
2043 { TS(86400,0), fTS | TS::fSS_Precision1, "1 day", "1d" },
2044 { TS(86400,0), fTS | TS::fSS_Precision2, "1 day", "1d" },
2045 { TS(86400,0), fTS | TS::fSS_Precision3, "1 day", "1d" },
2046 { TS(86400,0), fTS | TS::fSS_Precision4, "1 day", "1d" },
2047 { TS(86400,0), fTS | TS::fSS_Precision5, "1 day", "1d" },
2048 { TS(86400,0), fTS | TS::fSS_Precision6, "1 day", "1d" },
2049 { TS(86400,0), fTS | TS::fSS_Precision7, "1 day", "1d" },
2050
2051 // Some long time
2052 // "1 year 6 months 11 days 0 hours 59 minutes 41 seconds"
2053 // kAverageSecondsPerYear + kAverageSecondsPerMonth*6 + 11*24*3600 + 59*60 + 41 == 48289409 sec
2054
2055 { TS(48289409,900500), fTN | TS::fSS_Year, "1 year", "1y" },
2056 { TS(48289409,900500), fTN | TS::fSS_Month, "1 year 6 months", "1y 6mo" },
2057 { TS(48289409,900500), fTN | TS::fSS_Day, "1 year 6 months 11 days", "1y 6mo 11d" },
2058 { TS(48289409,900500), fTN | TS::fSS_Minute, "1 year 6 months 11 days 0 hours 59 minutes", "1y 6mo 11d 0h 59m" },
2059 { TS(48289409,900500), fTN | TS::fSS_Second, "1 year 6 months 11 days 0 hours 59 minutes 41 seconds", "1y 6mo 11d 0h 59m 41s" },
2060 { TS(48289409,900500), fTN | TS::fSS_Millisecond, "1 year 6 months 11 days 0 hours 59 minutes 41 seconds", "1y 6mo 11d 0h 59m 41s" },
2061 { TS(48289409,900500), fTN | TS::fSS_Microsecond, "1 year 6 months 11 days 0 hours 59 minutes 41 seconds 900 microseconds", "1y 6mo 11d 0h 59m 41s 900us" },
2062 { TS(48289409,900500), fTN | TS::fSS_Nanosecond, "1 year 6 months 11 days 0 hours 59 minutes 41 seconds 900500 nanoseconds", "1y 6mo 11d 0h 59m 41s 900500ns" },
2063 { TS(48289409,900500), fTN | TS::fSS_Precision1, "1 year", "1y" },
2064 { TS(48289409,900500), fTN | TS::fSS_Precision2, "1 year 6 months", "1y 6mo" },
2065 { TS(48289409,900500), fTN | TS::fSS_Precision3, "1 year 6 months 11 days", "1y 6mo 11d" },
2066 { TS(48289409,900500), fTN | TS::fSS_Precision4, "1 year 6 months 11 days", "1y 6mo 11d" },
2067 { TS(48289409,900500), fTN | TS::fSS_Precision5, "1 year 6 months 11 days 0 hours 59 minutes", "1y 6mo 11d 0h 59m" },
2068 { TS(48289409,900500), fTN | TS::fSS_Precision6, "1 year 6 months 11 days 0 hours 59 minutes 41 seconds", "1y 6mo 11d 0h 59m 41s" },
2069 { TS(48289409,900500), fTN | TS::fSS_Precision7, "1 year 6 months 11 days 0 hours 59 minutes 41 seconds", "1y 6mo 11d 0h 59m 41s" },
2070
2071 { TS(48289409,900500), fTS | TS::fSS_Year, "1 year", "1y" },
2072 { TS(48289409,900500), fTS | TS::fSS_Month, "1 year 6 months", "1y 6mo" },
2073 { TS(48289409,900500), fTS | TS::fSS_Day, "1 year 6 months 11 days", "1y 6mo 11d" },
2074 { TS(48289409,900500), fTS | TS::fSS_Minute, "1 year 6 months 11 days 59 minutes", "1y 6mo 11d 59m" },
2075 { TS(48289409,900500), fTS | TS::fSS_Second, "1 year 6 months 11 days 59 minutes 41 seconds", "1y 6mo 11d 59m 41s" },
2076 { TS(48289409,900500), fTS | TS::fSS_Millisecond, "1 year 6 months 11 days 59 minutes 41 seconds", "1y 6mo 11d 59m 41s" },
2077 { TS(48289409,900500), fTS | TS::fSS_Microsecond, "1 year 6 months 11 days 59 minutes 41 seconds 900 microseconds", "1y 6mo 11d 59m 41s 900us" },
2078 { TS(48289409,900500), fTS | TS::fSS_Nanosecond, "1 year 6 months 11 days 59 minutes 41 seconds 900500 nanoseconds", "1y 6mo 11d 59m 41s 900500ns" },
2079 { TS(48289409,900500), fTS | TS::fSS_Precision1, "1 year", "1y" },
2080 { TS(48289409,900500), fTS | TS::fSS_Precision2, "1 year 6 months", "1y 6mo" },
2081 { TS(48289409,900500), fTS | TS::fSS_Precision3, "1 year 6 months 11 days", "1y 6mo 11d" },
2082 { TS(48289409,900500), fTS | TS::fSS_Precision4, "1 year 6 months 11 days", "1y 6mo 11d" },
2083 { TS(48289409,900500), fTS | TS::fSS_Precision5, "1 year 6 months 11 days 59 minutes", "1y 6mo 11d 59m" },
2084 { TS(48289409,900500), fTS | TS::fSS_Precision6, "1 year 6 months 11 days 59 minutes 41 seconds", "1y 6mo 11d 59m 41s" },
2085 { TS(48289409,900500), fTS | TS::fSS_Precision7, "1 year 6 months 11 days 59 minutes 41 seconds", "1y 6mo 11d 59m 41s" },
2086
2087 { TS(48289409,900500), fRN | TS::fSS_Year, "2 years", "2y" },
2088 { TS(48289409,900500), fRN | TS::fSS_Month, "1 year 6 months", "1y 6mo" },
2089 { TS(48289409,900500), fRN | TS::fSS_Day, "1 year 6 months 11 days", "1y 6mo 11d" },
2090 { TS(48289409,900500), fRN | TS::fSS_Minute, "1 year 6 months 11 days 1 hour", "1y 6mo 11d 1h" },
2091 { TS(48289409,900500), fRN | TS::fSS_Second, "1 year 6 months 11 days 0 hours 59 minutes 41 seconds", "1y 6mo 11d 0h 59m 41s" },
2092 { TS(48289409,900500), fRN | TS::fSS_Millisecond, "1 year 6 months 11 days 0 hours 59 minutes 41 seconds 1 millisecond", "1y 6mo 11d 0h 59m 41s 1ms" },
2093 { TS(48289409,900500), fRN | TS::fSS_Microsecond, "1 year 6 months 11 days 0 hours 59 minutes 41 seconds 901 microseconds", "1y 6mo 11d 0h 59m 41s 901us" },
2094 { TS(48289409,900500), fRN | TS::fSS_Nanosecond, "1 year 6 months 11 days 0 hours 59 minutes 41 seconds 900500 nanoseconds", "1y 6mo 11d 0h 59m 41s 900500ns" },
2095 { TS(48289409,900500), fRN | TS::fSS_Precision1, "2 years", "2y" },
2096 { TS(48289409,900500), fRN | TS::fSS_Precision2, "1 year 6 months", "1y 6mo" },
2097 { TS(48289409,900500), fRN | TS::fSS_Precision3, "1 year 6 months 11 days", "1y 6mo 11d" },
2098 { TS(48289409,900500), fRN | TS::fSS_Precision4, "1 year 6 months 11 days 1 hour", "1y 6mo 11d 1h" },
2099 { TS(48289409,900500), fRN | TS::fSS_Precision5, "1 year 6 months 11 days 1 hour", "1y 6mo 11d 1h" },
2100 { TS(48289409,900500), fRN | TS::fSS_Precision6, "1 year 6 months 11 days 0 hours 59 minutes 41 seconds", "1y 6mo 11d 0h 59m 41s" },
2101 { TS(48289409,900500), fRN | TS::fSS_Precision7, "1 year 6 months 11 days 0 hours 59 minutes 41 seconds", "1y 6mo 11d 0h 59m 41s" },
2102
2103 { TS(48289409,900500), fRS | TS::fSS_Year, "2 years", "2y" },
2104 { TS(48289409,900500), fRS | TS::fSS_Month, "1 year 6 months", "1y 6mo" },
2105 { TS(48289409,900500), fRS | TS::fSS_Day, "1 year 6 months 11 days", "1y 6mo 11d" },
2106 { TS(48289409,900500), fRS | TS::fSS_Minute, "1 year 6 months 11 days 1 hour", "1y 6mo 11d 1h" },
2107 { TS(48289409,900500), fRS | TS::fSS_Second, "1 year 6 months 11 days 59 minutes 41 seconds", "1y 6mo 11d 59m 41s" },
2108 { TS(48289409,900500), fRS | TS::fSS_Millisecond, "1 year 6 months 11 days 59 minutes 41 seconds 1 millisecond", "1y 6mo 11d 59m 41s 1ms" },
2109 { TS(48289409,900500), fRS | TS::fSS_Microsecond, "1 year 6 months 11 days 59 minutes 41 seconds 901 microseconds", "1y 6mo 11d 59m 41s 901us" },
2110 { TS(48289409,900500), fRS | TS::fSS_Nanosecond, "1 year 6 months 11 days 59 minutes 41 seconds 900500 nanoseconds", "1y 6mo 11d 59m 41s 900500ns" },
2111 { TS(48289409,900500), fRS | TS::fSS_Precision1, "2 years", "2y" },
2112 { TS(48289409,900500), fRS | TS::fSS_Precision2, "1 year 6 months", "1y 6mo" },
2113 { TS(48289409,900500), fRS | TS::fSS_Precision3, "1 year 6 months 11 days", "1y 6mo 11d" },
2114 { TS(48289409,900500), fRS | TS::fSS_Precision4, "1 year 6 months 11 days 1 hour", "1y 6mo 11d 1h" },
2115 { TS(48289409,900500), fRS | TS::fSS_Precision5, "1 year 6 months 11 days 1 hour", "1y 6mo 11d 1h" },
2116 { TS(48289409,900500), fRS | TS::fSS_Precision6, "1 year 6 months 11 days 59 minutes 41 seconds", "1y 6mo 11d 59m 41s" },
2117 { TS(48289409,900500), fRS | TS::fSS_Precision7, "1 year 6 months 11 days 59 minutes 41 seconds", "1y 6mo 11d 59m 41s" },
2118
2119 // stopper
2120 { TS(0,0), TS::fSS_Default, NULL, NULL }
2121 };
2122
2123 for (int i = 0; s_Test[i].res_full; i++) {
2124
2125 // timespan -> string
2126
2127 string s_full = s_Test[i].timespan.AsSmartString(s_Test[i].flags | TS::fSS_Full);
2128 string s_short = s_Test[i].timespan.AsSmartString(s_Test[i].flags | TS::fSS_Short);
2129 #if 1
2130 assert(s_full == s_Test[i].res_full);
2131 assert(s_short == s_Test[i].res_short);
2132 #else
2133 if (s_full != s_Test[i].res_full) {
2134 cout << i << ". Print:" << s_full << " != " << s_Test[i].res_full << endl;
2135 }
2136 if (s_short != s_Test[i].res_short) {
2137 cout << i << ". Print:" << s_short << " != " << s_Test[i].res_short << endl;
2138 }
2139 #endif
2140
2141 // string -> timespan -> string (AssignFromSmartString() test)
2142
2143 CTimeSpan ts;
2144 ts.AssignFromSmartString(s_full);
2145 string s_full_new = ts.AsSmartString(s_Test[i].flags | TS::fSS_Full);
2146 ts.AssignFromSmartString(s_short);
2147 string s_short_new = ts.AsSmartString(s_Test[i].flags | TS::fSS_Short);
2148 #if 1
2149 assert(s_full_new == s_Test[i].res_full);
2150 assert(s_short_new == s_Test[i].res_short);
2151 #else
2152 if (s_full_new != s_Test[i].res_full) {
2153 cout << i << ". Assign:" << s_full_new << " != " << s_Test[i].res_full << endl;
2154 }
2155 if (s_short_new != s_Test[i].res_short) {
2156 cout << i << ". Assign:" << s_short_new << " != " << s_Test[i].res_short << endl;
2157 }
2158 #endif
2159 }
2160 }
2161
2162
2163
2164 //============================================================================
2165 //
2166 // TestTimeout
2167 //
2168 //============================================================================
2169
s_TestTimeout(void)2170 static void s_TestTimeout(void)
2171 {
2172 unsigned long ms;
2173 double ds;
2174 CTimeout tmo_default;
2175 CTimeout tmo_infinite(CTimeout::eInfinite);
2176 CTimeout tmo_zero(CTimeout::eZero);
2177
2178 // Special values
2179 {{
2180 assert(tmo_default.IsDefault());
2181 assert(tmo_infinite.IsInfinite());
2182 assert(tmo_zero.IsZero());
2183 try {
2184 tmo_default.GetAsDouble();
2185 _TROUBLE;
2186 }
2187 catch (CTimeException&) {}
2188 try {
2189 tmo_infinite.GetAsDouble();
2190 _TROUBLE;
2191 }
2192 catch (CTimeException&) {}
2193 assert(!tmo_infinite.IsZero());
2194 try {
2195 // Default value cannot be check on zero, unlike infinite timeout.
2196 assert(tmo_default.IsZero());
2197 _TROUBLE;
2198 }
2199 catch (CTimeException&) {}
2200 }}
2201
2202 // Constructors
2203 {{
2204 CTimeout t1(3,400000);
2205 ms = t1.GetAsMilliSeconds();
2206 ds = t1.GetAsDouble();
2207 assert(ms == 3400);
2208 assert(ds > 3.3 && ds < 3.5);
2209 t1.Set(1,2000);
2210 assert(t1.GetAsMilliSeconds() == 1002);
2211
2212 CTimeout t2(6.75);
2213 ms = t2.GetAsMilliSeconds();
2214 ds = t2.GetAsDouble();
2215 assert(ms > 6749 && ms < 6751);
2216 assert(ds > 6.74 && ds < 6.76);
2217 t1.Set(1,2000);
2218 assert(t1.GetAsMilliSeconds() == 1002);
2219
2220 CTimeout t3(t1);
2221 assert(t3.GetAsMilliSeconds() == 1002);
2222 t3 = t1;
2223 assert(t1.GetAsMilliSeconds() == 1002);
2224 t3 = tmo_default;
2225 assert(t3.IsDefault());
2226 t3 = tmo_infinite;
2227 assert(t3.IsInfinite());
2228 }}
2229 {{
2230 CTimeSpan ts;
2231 CTimeSpan ts1(1,200);
2232 CTimeSpan ts2(1,200000);
2233 CTimeSpan ts3(-1,200);
2234
2235 CTimeout t(ts1);
2236 // Nanoseconds truncates to 0 here
2237 ts = t.GetAsTimeSpan();
2238 assert(ts.GetCompleteSeconds() == 1);
2239 assert(ts.GetNanoSecondsAfterSecond() == 200);
2240 assert(ts == ts1);
2241
2242 // Microseconds correcly converts to nanoseconds
2243 t = ts2;
2244 ts = t.GetAsTimeSpan();
2245 assert(ts.GetCompleteSeconds() == 1);
2246 assert(ts.GetNanoSecondsAfterSecond() == 200000);
2247 assert(ts == ts2);
2248
2249 // Cannot copy from negative time span
2250 try {
2251 t = ts3;
2252 _TROUBLE;
2253 }
2254 catch (CTimeException&) {}
2255 }}
2256
2257 // Check Get()
2258 {{
2259 CTimeout t(123, 456);
2260 unsigned int sec, usec;
2261 t.Get(&sec, &usec);
2262 assert(sec == 123);
2263 assert(usec == 456);
2264 t.Set(CTimeout::eInfinite);
2265 try {
2266 t.Get(&sec, &usec);
2267 _TROUBLE;
2268 }
2269 catch (CTimeException&) {}
2270 }}
2271
2272 // Comparison
2273 {{
2274 CTimeout t0;
2275 CTimeout ti(CTimeout::eInfinite);
2276 CTimeout t1(123.4);
2277 CTimeout t2(123.45);
2278 CTimeout t3(123.4);
2279
2280 // Compare finite timeouts
2281 assert(t1 != t2);
2282 assert(t1 == t3);
2283 assert(t1 < t2);
2284 assert(t2 > t1);
2285 assert(t1 <= t2);
2286 assert(t2 >= t2);
2287
2288 // Compare infinite timeout
2289 assert(t1 > tmo_zero);
2290 assert(t1 < tmo_infinite);
2291 assert(t1 <= tmo_infinite);
2292 assert(!(t1 > tmo_infinite));
2293 assert(ti == tmo_infinite);
2294 assert(tmo_infinite == tmo_infinite);
2295
2296 // Default timeout is almost not comparable
2297 try {
2298 assert(t0 == tmo_default);
2299 _TROUBLE;
2300 }
2301 catch (CTimeException&) {}
2302 try {
2303 assert(t1 < tmo_default);
2304 _TROUBLE;
2305 }
2306 catch (CTimeException&) {}
2307 try {
2308 assert(tmo_default == tmo_default);
2309 _TROUBLE;
2310 }
2311 catch (CTimeException&) {}
2312 try {
2313 assert(tmo_default == tmo_infinite);
2314 _TROUBLE;
2315 }
2316 catch (CTimeException&) {}
2317 try {
2318 assert(tmo_default != tmo_infinite);
2319 _TROUBLE;
2320 }
2321 catch (CTimeException&) {}
2322 try {
2323 assert(t1 != tmo_default);
2324 _TROUBLE;
2325 }
2326 catch (CTimeException&) {}
2327 try {
2328 assert(tmo_default > tmo_zero);
2329 _TROUBLE;
2330 }
2331 catch (CTimeException&) {}
2332 try {
2333 assert(tmo_default < tmo_infinite);
2334 _TROUBLE;
2335 }
2336 catch (CTimeException&) {}
2337 try {
2338 assert(tmo_zero < tmo_default);
2339 _TROUBLE;
2340 }
2341 catch (CTimeException&) {}
2342 try {
2343 assert(tmo_infinite > tmo_default);
2344 _TROUBLE;
2345 }
2346 catch (CTimeException&) {}
2347
2348 // Only >= and <= can be applied in some cases
2349 assert(tmo_infinite >= tmo_default);
2350 assert(tmo_default <= tmo_infinite);
2351 assert(tmo_default >= tmo_zero);
2352 assert(tmo_zero <= tmo_default);
2353 }}
2354
2355 // Assignment
2356 {{
2357 CTimeout t1(1.23);
2358 CTimeout t2(4.56);
2359 t1 = t2;
2360 assert(t1 == t2);
2361 t1 = tmo_default;
2362 assert(t1.IsDefault());
2363 try {
2364 // assert(t1 != t2);
2365 (void)(t1 != t2);
2366 _TROUBLE;
2367 }
2368 catch (CTimeException&) {}
2369 }}
2370 }
2371
2372
2373 //============================================================================
2374 //
2375 // DemoStopWatch
2376 //
2377 //============================================================================
2378
s_DemoStopWatch(void)2379 static void s_DemoStopWatch(void)
2380 {
2381 for ( int t = 0; t < 2; ++t ) {
2382 CStopWatch sw;
2383 assert(!sw.IsRunning());
2384 assert(sw.Elapsed() == 0);
2385 if ( t == 0 ) {
2386 sw.Start();
2387 }
2388 else {
2389 assert(sw.Restart() == 0);
2390 }
2391 assert(sw.IsRunning());
2392 sw.SetFormat("S.n");
2393
2394 CNcbiOstrstream s;
2395 for (int i=0; i<10; i++) {
2396 s << sw << endl;
2397 }
2398 assert(sw.IsRunning());
2399 sw.Stop();
2400 assert(!sw.IsRunning());
2401 SleepMilliSec(500);
2402 sw.Start();
2403 for (int i=0; i<10; i++) {
2404 s << sw << endl;
2405 }
2406 //ERR_POST(Note << (string)CNcbiOstrstreamToString(s));
2407 }
2408 }
2409
2410
2411 //============================================================================
2412 //
2413 // MAIN
2414 //
2415 //============================================================================
2416
main()2417 int main()
2418 {
2419 // Set err.-posting and tracing to maximum
2420 SetDiagTrace(eDT_Enable);
2421 SetDiagPostFlag(eDPF_All);
2422 SetDiagPostLevel(eDiag_Info);
2423
2424 // Reinit global timezone variables
2425 NcbiSys_tzset();
2426
2427 // Run tests
2428 try {
2429 s_TestMisc();
2430 s_TestFormats();
2431 s_TestUTC();
2432 #if ENABLE_SPEED_TESTS
2433 s_TestUTCSpeed();
2434 #endif
2435 s_TestTimeSpan();
2436 s_TestTimeSpan_AsSmartString();
2437 s_TestTimeSpan_AssignFromSmartString();
2438 s_TestTimeout();
2439 s_DemoStopWatch();
2440 } catch (CException& e) {
2441 ERR_FATAL(e);
2442 }
2443 // Success
2444 return 0;
2445 }
2446