PLplot 5.15.0
Loading...
Searching...
No Matches
qsastime_testlib.c
Go to the documentation of this file.
1//
2// Copyright (C) 2009 Alan W. Irwin
3//
4// This file is part of PLplot.
5//
6// PLplot is free software; you can redistribute it and/or modify
7// it under the terms of the GNU Library General Public License as published
8// by the Free Software Foundation; either version 2 of the License, or
9// (at your option) any later version.
10//
11// PLplot is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14// GNU Library General Public License for more details.
15//
16// You should have received a copy of the GNU Library General Public License
17// along with PLplot; if not, write to the Free Software
18// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19//
20//
21#include "qsastime.h"
22#include "qsastimeP.h"
23#include <time.h>
24#include <stdio.h>
25#include <stdlib.h>
26#include <math.h>
27#include <errno.h>
28
29#define TEST01 0x1
30#define TEST02 0x2
31#define TEST03 0x4
32#define TEST04 0x8
33#define TEST05 0x10
34#define TEST06 0x20
35#define TEST07 0x40
36#define TEST08 0x80
37#define TEST09 0x100
38#define TEST10 0x200
39#define TEST11 0x400
40#define TEST12 0x800
41#define TEST13 0x1000
42#define TEST14 0x2000
43#define TEST15 0x4000
44#define TEST16 0x8000
45// MJD for Jan 01, 1970 00:00:00 Gregorian, the Unix epoch.
46#define MJD_1970 40587
47
48// Recommended (by Linux timegm man page) POSIX equivalent of Linux timegm C library function
49time_t my_timegm( struct tm *tm )
50{
51 time_t ret;
52 char *tz;
53
54 tz = getenv( "TZ" );
55 setenv( "TZ", "", 1 );
56 tzset();
57 ret = mktime( tm );
58 if ( tz )
59 setenv( "TZ", tz, 1 );
60 else
61 unsetenv( "TZ" );
62 tzset();
63 return ret;
64}
65
66int testlib_broken_down_time( int year, int month, int day, int hour, int min, double sec, int forceJulian, int inner_test_choice, int verbose )
67{
68 char buf[360];
69 int year1, month1, day1, hour1, min1;
70 double sec1;
71 struct tm tm;
72 struct tm *ptm = &tm;
73 struct tm tm1;
74 struct tm *ptm1 = &tm1;
75 time_t secs_past_epoch, secs_past_epoch1, delta_secs;
76
77 MJDtime MJD1, *pMJD1 = &MJD1;
78 double jd;
79 int ifleapyear, ifleapday, iffeb29, ifsamedate, ifsametime;
80 ptm->tm_year = year - 1900;
81 ptm->tm_mon = month;
82 ptm->tm_mday = day;
83 ptm->tm_hour = hour;
84 ptm->tm_min = min;
85 ptm->tm_sec = (int) sec;
86 if ( verbose )
87 {
88 if ( forceJulian )
89 {
90 printf( "Start of Julian proleptic inner test\n" );
91 printf( "input and output (strfMJD) date/time\n" );
92 }
93 else
94 {
95 printf( "Start of Gregorian proleptic inner test\n" );
96 printf( "input and output (strftime), and output (strfMJD) date/time\n" );
97 }
98 printf( "%.4d-%02d-%02dT%02d:%02d:%018.15fZ\n", year, month + 1, day, hour, min, sec );
99 }
100
101 setFromUT( year, month, day, hour, min, sec, pMJD1, forceJulian );
102
103 // Inner TEST01: compare setFromUT with my_timegm.
104 if ( !forceJulian && ( inner_test_choice & TEST01 ) )
105 {
106 secs_past_epoch1 = (time_t) ( 86400. * ( (double) pMJD1->base_day - (double) MJD_1970 ) + (int) pMJD1->time_sec );
107 secs_past_epoch = my_timegm( ptm );
108 delta_secs = abs( secs_past_epoch1 - secs_past_epoch );
109 if ( delta_secs != 0 )
110 {
111 printf( "setFromUT secs_past_epoch = %lld seconds\n", (long long) secs_past_epoch1 );
112 printf( "my_timegm secs_past_epoch = %lld seconds\n", (long long) secs_past_epoch );
113 printf( "delta secs_past_epoch = %lld seconds\n", (long long) ( secs_past_epoch1 - secs_past_epoch ) );
114 printf( "test failed with inconsistency between setFromUT and my_timegm\n" );
115 return 1;
116 }
117 }
118
119 // Inner TEST02: check minimal fields of strfMJD (Julian) or
120 // strftime and strfMJD (Gregorian)
121 if ( inner_test_choice & TEST02 )
122 {
123 if ( !forceJulian )
124 {
125 strftime( &( buf[0] ), 360, "%Y-%m-%dT%H:%M:%SZ\n", ptm );
126 if ( verbose )
127 printf( "%s", buf );
128 }
129 strfMJD( &( buf[0] ), 360, "%Y-%m-%dT%H:%M:%S%.Z\n", pMJD1, forceJulian, 0 );
130 if ( verbose )
131 printf( "%s", buf );
132 }
133
134 if ( verbose )
135 {
136 jd = 2400000.5 + pMJD1->base_day + pMJD1->time_sec / 86400.;
137 printf( "setFromUT JD = %25.16f days\n", jd );
138 }
139
140 if ( forceJulian )
141 ifleapyear = ( year % 4 == 0 );
142 else
143 ifleapyear = ( ( year % 4 == 0 && year % 100 != 0 ) || year % 400 == 0 );
144 iffeb29 = month == 1 && day == 29;
145 ifleapday = ( ifleapyear && iffeb29 );
146
147 // Inner TEST03: compare setFromUT with its inverse, breakDownMJD
148 if ( inner_test_choice & TEST03 )
149 {
150 breakDownMJD( &year1, &month1, &day1, &hour1, &min1, &sec1, pMJD1, forceJulian );
151 ifsamedate = ( year1 - year == 0 && ( ( ( !iffeb29 || ifleapday ) && ( month1 - month == 0 && day1 - day == 0 ) ) || ( ( iffeb29 && !ifleapday ) && ( month1 == 2 && day1 == 1 ) ) ) );
152 ifsametime = ( hour1 - hour == 0 && min1 - min == 0 && fabs( sec1 - sec ) < 1.e-10 );
153
154 if ( !( ifsamedate && ifsametime ) )
155 {
156 printf( "output date calculated with breakDownMJD = %d-%02d-%02dT%02d:%02d:%018.15fZ\n", year1, month1 + 1, day1, hour1, min1, sec1 );
157 printf( "test failed with inconsistency between setFromUT and breakDownMJD\n" );
158 return 1;
159 }
160 }
161
162 // Inner TEST04: compare setFromUT with its inverse, the C library gmtime.
163 if ( !forceJulian && ( inner_test_choice & TEST04 ) )
164 {
165 ptm1 = gmtime( &secs_past_epoch );
166 ifsamedate = ( ptm1->tm_year == ptm->tm_year && ( ( ( !iffeb29 || ifleapday ) && ( ptm1->tm_mon == ptm->tm_mon && ptm1->tm_mday == ptm->tm_mday ) ) || ( ( iffeb29 && !ifleapday ) && ( ptm1->tm_mon == 2 && ptm1->tm_mday == 1 ) ) ) );
167 ifsametime = ( ptm1->tm_hour == ptm->tm_hour && ptm1->tm_min == ptm->tm_min && ptm1->tm_sec == ptm->tm_sec );
168
169 if ( !( ifsamedate && ifsametime ) )
170 {
171 printf( "test failed with inconsistency between my_timegm and its C library inverse gmtime" );
172 return 1;
173 }
174 }
175 return 0;
176}
177
178int testlib_MJD( const MJDtime *MJD, int forceJulian, int inner_test_choice, int verbose )
179{
180 int year, month, day, hour, min;
181 double sec;
182 char buf[360];
183 int year1, month1, day1, hour1, min1;
184 double sec1;
185 struct tm tm;
186 struct tm *ptm = &tm;
187 struct tm tm1;
188 struct tm *ptm1 = &tm1;
189 time_t secs_past_epoch, secs_past_epoch1;
190
191 MJDtime MJD1_value, *MJD1 = &MJD1_value;
192 MJDtime MJD2_value, *MJD2 = &MJD2_value;
193 double jd;
194 int ifleapyear, ifleapday, iffeb29, ifsamedate, ifsametime;
195
196 *MJD1 = *MJD;
197 normalize_MJD( MJD1 );
198 secs_past_epoch = (time_t) ( 86400. * ( (double) MJD1->base_day - (double) MJD_1970 ) + MJD1->time_sec );
199 breakDownMJD( &year, &month, &day, &hour, &min, &sec, MJD1, forceJulian );
200
201 ptm->tm_year = year - 1900;
202 ptm->tm_mon = month;
203 ptm->tm_mday = day;
204 ptm->tm_hour = hour;
205 ptm->tm_min = min;
206 ptm->tm_sec = (int) sec;
207 if ( verbose )
208 {
209 if ( forceJulian )
210 {
211 printf( "Start of Julian proleptic inner test\n" );
212 printf( "input and output (strfMJD) date/time\n" );
213 }
214 else
215 {
216 printf( "Start of Gregorian proleptic inner test\n" );
217 printf( "input and output (strftime), and output (strfMJD) date/time\n" );
218 }
219 printf( "%.4d-%02d-%02dT%02d:%02d:%018.15fZ\n", year, month + 1, day, hour, min, sec );
220 }
221
222 // Inner TEST01: compare breakDownMJD with gmtime.
223 if ( !forceJulian && ( inner_test_choice & TEST01 ) )
224 {
225 ptm1 = gmtime( &secs_past_epoch );
226 if ( !( ( ptm1->tm_year + 1900 ) == year && ptm1->tm_mon == month && ptm1->tm_mday == day && ptm1->tm_hour == hour && ptm1->tm_min == min && ptm1->tm_sec == (int) sec ) )
227 {
228 printf( "date calculated with breakDownMJD = %d-%02d-%02dT%02d:%02d:%018.15fZ\n", year, month + 1, day, hour, min, sec );
229 printf( "date calculated with gmtime = %d-%02d-%02dT%02d:%02d:%02dZ\n", ptm1->tm_year + 1900, ptm1->tm_mon + 1, ptm1->tm_mday, ptm1->tm_hour, ptm1->tm_min, ptm1->tm_sec );
230 printf( "test failed with inconsistency between breakDownMJD and gmtime\n" );
231 return 1;
232 }
233 }
234
235 // Inner TEST02: check minimal fields of strfMJD (Julian) or
236 // strftime and strfMJD (Gregorian)
237 if ( inner_test_choice & TEST02 )
238 {
239 if ( !forceJulian )
240 {
241 strftime( &( buf[0] ), 360, "%Y-%m-%dT%H:%M:%SZ\n", ptm );
242 if ( verbose )
243 printf( "%s", buf );
244 }
245 strfMJD( &( buf[0] ), 360, "%Y-%m-%dT%H:%M:%S%.Z\n", MJD1, forceJulian, 0 );
246 if ( verbose )
247 printf( "%s", buf );
248 }
249
250 if ( verbose )
251 {
252 jd = 2400000.5 + MJD1->base_day + MJD1->time_sec / 86400.;
253 printf( "JD = %25.16f days\n", jd );
254 }
255
256 if ( forceJulian )
257 ifleapyear = ( year % 4 == 0 );
258 else
259 ifleapyear = ( ( year % 4 == 0 && year % 100 != 0 ) || year % 400 == 0 );
260 iffeb29 = month == 1 && day == 29;
261 ifleapday = ( ifleapyear && iffeb29 );
262
263 // Inner TEST03: compare breakDownMJD with its inverse, setFromUT
264 if ( inner_test_choice & TEST03 )
265 {
266 setFromUT( year, month, day, hour, min, sec, MJD2, forceJulian );
267 if ( !( MJD2->time_sec == MJD1->time_sec && MJD2->base_day == MJD1->base_day ) )
268 {
269 printf( "(normalized) input MJD components are = %d, %f\n", MJD1->base_day, MJD1->time_sec );
270 printf( "(output MJD2 components generated by setFromUT are = %d, %f\n", MJD2->base_day, MJD2->time_sec );
271 printf( "test failed with inconsistency between breakDownMJD and setFromUT\n" );
272 return 1;
273 }
274 }
275
276 // Inner TEST04: compare breakDownMJD with its inverse, my_timegm
277 if ( !forceJulian && ( inner_test_choice & TEST04 ) )
278 {
279 secs_past_epoch1 = my_timegm( ptm );
280 if ( !( secs_past_epoch == secs_past_epoch1 ) )
281 {
282 printf( "secs_past_epoch calculated from input = %lld\n", (long long) secs_past_epoch );
283 printf( "secs_past_epoch calculated from my_timegm = %lld\n", (long long) secs_past_epoch1 );
284 printf( "delta secs_past_epoch = %lld seconds\n", (long long) ( secs_past_epoch1 - secs_past_epoch ) );
285 printf( "test failed with inconsistency between breakDownMJD and its C library based inverse, my_timegm\n" );
286 return 1;
287 }
288 }
289 return 0;
290}
291
292// Test program to do extensive comparisons between setFromUT, breakDownMJD,
293// and strfMJD and the closest corresponding _Linux_ C library routines,
294// timegm, gmtime, and strftime.
295
296int main()
297{
298 char buf[360];
299 char buf1[360];
300 int year, month, day, hour, min;
301 double sec;
302 int year1, month1, day1, hour1, min1;
303 double sec1;
304 struct tm tm;
305 struct tm *ptm = &tm;
306 struct tm tm1;
307 struct tm *ptm1 = &tm1;
308 int seconds;
309
310 MJDtime MJD1_value, *MJD1 = &MJD1_value;
311 double jd;
312 int test_choice, date_choice, ret;
313
314 // choose test(s) to be run using bit-pattern in test_choice that is
315 // input from stdin.
316 scanf( "%i", &test_choice );
317
318 printf( "sizeof(time_t) = %d\n", (int) sizeof ( time_t ) );
319 if ( sizeof ( time_t ) < 8 )
320 {
321 printf( "tests abandoned because time_t is too small on this platform to represent the extremely large date range used for many of these tests. Note, the limitation is in the C library routines (gmtime and mktime) used for these test comparisons and not libqsastime itself.\n" );
322 return 1;
323 }
324
325 printf( "sizeof(int) = %d\n", (int) sizeof ( int ) );
326 if ( sizeof ( int ) != 4 )
327 {
328 printf( "tests abandoned because int must be 32-bits to test this library properly for how well it will potentially perform on 32-bit platforms\n" );
329 return 2;
330 }
331 // strftime affected by locale so force 0 timezone for this complete test.
332 setenv( "TZ", "", 1 );
333 tzset();
334
335 if ( test_choice & TEST01 )
336 {
337 printf( "Test 01 of calendar dates in the vicinity of the JD epoch \n" );
338
339 for ( date_choice = 0; date_choice < 5; date_choice++ )
340 {
341 if ( date_choice == 0 )
342 {
343 month = 0;
344 day = 1;
345 }
346 else if ( date_choice == 1 )
347 {
348 month = 1;
349 day = 28;
350 }
351 else if ( date_choice == 2 )
352 {
353 month = 1;
354 day = 29;
355 }
356 else if ( date_choice == 3 )
357 {
358 month = 2;
359 day = 1;
360 }
361 else if ( date_choice == 4 )
362 {
363 month = 11;
364 day = 31;
365 }
366 hour = 12;
367 min = 0;
368 sec = 0.;
369
370 for ( year = -4717; year <= -4707; year++ )
371 {
372 printf( "\n" );
373 ret = testlib_broken_down_time( year, month, day, hour, min, sec, 1, 0xffff, 1 );
374 if ( ret )
375 return ret;
376 ret = testlib_broken_down_time( year, month, day, hour, min, sec, 0, 0xffff, 1 );
377 if ( ret )
378 return ret;
379 }
380 }
381 }
382
383 if ( test_choice & TEST02 )
384 {
385 printf( "Test 02 of calendar dates in the vicinity of the year epoch. \n" );
386
387 for ( date_choice = 0; date_choice < 5; date_choice++ )
388 {
389 if ( date_choice == 0 )
390 {
391 month = 0;
392 day = 1;
393 }
394 else if ( date_choice == 1 )
395 {
396 month = 1;
397 day = 28;
398 }
399 else if ( date_choice == 2 )
400 {
401 month = 1;
402 day = 29;
403 }
404 else if ( date_choice == 3 )
405 {
406 month = 2;
407 day = 1;
408 }
409 else if ( date_choice == 4 )
410 {
411 month = 11;
412 day = 31;
413 }
414 hour = 0;
415 min = 0;
416 sec = 0.;
417
418 for ( year = -5; year <= 5; year++ )
419 {
420 printf( "\n" );
421 ret = testlib_broken_down_time( year, month, day, hour, min, sec, 1, 0xffff, 1 );
422 if ( ret )
423 return ret;
424 ret = testlib_broken_down_time( year, month, day, hour, min, sec, 0, 0xffff, 1 );
425 if ( ret )
426 return ret;
427 }
428 }
429 }
430
431 if ( test_choice & TEST03 )
432 {
433 printf( "Test 03 of calendar dates in the vicinity of the MJD epoch. \n" );
434
435 for ( date_choice = 0; date_choice < 6; date_choice++ )
436 {
437 if ( date_choice == 0 )
438 {
439 month = 0;
440 day = 1;
441 }
442 else if ( date_choice == 1 )
443 {
444 month = 1;
445 day = 28;
446 }
447 else if ( date_choice == 2 )
448 {
449 month = 1;
450 day = 29;
451 }
452 else if ( date_choice == 3 )
453 {
454 month = 2;
455 day = 1;
456 }
457 else if ( date_choice == 4 )
458 {
459 month = 10;
460 day = 17;
461 }
462 else if ( date_choice == 5 )
463 {
464 month = 11;
465 day = 31;
466 }
467 hour = 0;
468 min = 0;
469 sec = 0.;
470
471 for ( year = 1853; year <= 1863; year++ )
472 {
473 printf( "\n" );
474 ret = testlib_broken_down_time( year, month, day, hour, min, sec, 1, 0xffff, 1 );
475 if ( ret )
476 return ret;
477 ret = testlib_broken_down_time( year, month, day, hour, min, sec, 0, 0xffff, 1 );
478 if ( ret )
479 return ret;
480 }
481 }
482 }
483
484 if ( test_choice & TEST04 )
485 {
486 printf( "Test 04 of small second range near Year 0 (Julian)\n" );
487
488 ret = setFromUT( 0, 0, 1, 0, 0, 0., MJD1, 1 );
489 if ( ret )
490 {
491 printf( "Test 04 cannot even start for Year 0 (Julian)" );
492 return ret;
493 }
494
495 for ( seconds = -5; seconds < 5; seconds++ )
496 {
497 printf( "\n" );
498 ret = testlib_MJD( MJD1, 1, 0xffff, 1 );
499 if ( ret )
500 return ret;
501 MJD1->time_sec++;
502 }
503
504 printf( "Test 04 of small second range near Year 0 (Gregorian)\n" );
505
506
507 ret = setFromUT( 0, 0, 1, 0, 0, 0., MJD1, 0 );
508 if ( ret )
509 {
510 printf( "Test 04 cannot even start for Year 0 (Gregorian)" );
511 return ret;
512 }
513
514 for ( seconds = -5; seconds < 5; seconds++ )
515 {
516 printf( "\n" );
517 ret = testlib_MJD( MJD1, 0, 0xffff, 1 );
518 if ( ret )
519 return ret;
520 MJD1->time_sec++;
521 }
522
523 printf( "Test 04 of small second range near 2009-01-01 (Gregorian) when a leap second was inserted\n" );
524
525
526 ret = setFromUT( 2009, 0, 1, 0, 0, 0.1234567890123456 - 5., MJD1, 0 );
527 if ( ret )
528 {
529 printf( "Test 04 cannot even start for Year 0 (Gregorian)" );
530 return ret;
531 }
532
533 for ( seconds = -5; seconds < 5; seconds++ )
534 {
535 printf( "\n" );
536 ret = testlib_MJD( MJD1, 0, 0xffff, 1 );
537 if ( ret )
538 return ret;
539 MJD1->time_sec++;
540 }
541 }
542
543 if ( test_choice & TEST05 )
544 {
545 printf( "Test 05 of normalization of breakDownMJD result and strfMJD results near the hour.\n" );
546 MJD1->base_day = 51910;
547 MJD1->time_sec = 3600.;
548 int iepsilon;
549 for ( iepsilon = -1; iepsilon < 2; iepsilon++ )
550 {
551 MJD1->time_sec = 3600. + 1.e-8 * (double) iepsilon;
552 breakDownMJD( &year, &month, &day, &hour, &min, &sec, MJD1, 0 );
553 printf( "MJD = {%d,%20.15f}\n", MJD1->base_day, MJD1->time_sec );
554 printf( "breakDownMJD result is year, month, day, hour, min, sec = %d, %d, %d, %d, %d, %20.15f\n", year, month, day, hour, min, sec );
555 strfMJD( &( buf[0] ), 360, "%Y-%m-%dT%H:%M:%S%9Z\n", MJD1, 0, 0 );
556 printf( "strfMJD %%S%%9 result is %s", buf );
557 strfMJD( &( buf[0] ), 360, "%Y-%m-%dT%H:%M:%S%.Z\n", MJD1, 0, 0 );
558 printf( "strfMJD %%S%%. result is %s", buf );
559 strfMJD( &( buf[0] ), 360, "%H:%M:%S, %H:%M:%S%0, %H:%M:%S%1, %H:%M:%S%2, %H:%M:%S%3, %H:%M:%S%4\n %H:%M:%S %0,%H:%M:%S %1,%H:%M:%S %2,%H:%M:%S %3,%H:%M:%S %4\n", MJD1, 0, 0 );
560 printf( "strfMJD more heavily rounded results (the latter ones with a blank before the\ndecimal point to prove separated formatting works) for H:M:S are the following:\n%s", buf );
561 }
562 }
563
564 if ( test_choice & TEST06 )
565 {
566 printf( "Test 06 (non-verbose) of calendar dates for every year from -5000000 to 5000000\n" );
567
568 for ( date_choice = 0; date_choice < 5; date_choice++ )
569 {
570 if ( date_choice == 0 )
571 {
572 month = 0;
573 day = 1;
574 }
575 else if ( date_choice == 1 )
576 {
577 month = 1;
578 day = 28;
579 }
580 else if ( date_choice == 2 )
581 {
582 month = 1;
583 day = 29;
584 }
585 else if ( date_choice == 3 )
586 {
587 month = 2;
588 day = 1;
589 }
590 else if ( date_choice == 4 )
591 {
592 month = 11;
593 day = 31;
594 }
595 hour = 0;
596 min = 0;
597 sec = 0.123456;
598
599 // test reduced range of years that just barely misses overflowing
600 // the MJD integer. e.g., 6000000 overflows it.
601 for ( year = -5000000; year <= 5000000; year += 1 )
602 {
603 ret = testlib_broken_down_time( year, month, day, hour, min, sec, 1, 0xffff, 0 );
604 if ( ret )
605 return ret;
606 ret = testlib_broken_down_time( year, month, day, hour, min, sec, 0, 0xffff, 0 );
607 if ( ret )
608 return ret;
609 }
610 }
611 }
612
613 if ( test_choice & TEST07 )
614 {
615 printf( "Test 07 (non-verbose) of all seconds from late 2007 to early 2009\n" );
616 ret = setFromUT( 2007, 11, 30, 0, 0, 0., MJD1, 0 );
617 if ( ret )
618 {
619 printf( "Test 06 cannot even start" );
620 return ret;
621 }
622
623 // 430 days or ~ 37 million seconds should cover the complete next year for both Julian and Gregorian .
624 for ( seconds = 0; seconds < 430 * 86400; seconds++ )
625 {
626 MJD1->time_sec = (double) seconds;
627 ret = testlib_MJD( MJD1, 1, 0xffff, 0 );
628 if ( ret )
629 return ret;
630
631 ret = testlib_MJD( MJD1, 0, 0xffff, 0 );
632 if ( ret )
633 return ret;
634 }
635 }
636
637
638 return 0;
639}
#define min(x, y)
Definition nnpi.c:87
int setFromUT(int year, int month, int day, int hour, int min, double sec, MJDtime *MJD, int forceJulian)
Definition qsastime.c:71
void normalize_MJD(MJDtime *MJD)
Definition qsastime.c:270
void breakDownMJD(int *year, int *month, int *day, int *hour, int *min, double *sec, const MJDtime *MJD, int forceJulian)
Definition qsastime.c:289
size_t strfMJD(char *buf, size_t len, const char *format, const MJDtime *MJD, int forceJulian, int inleap)
Definition qsastime.c:365
int testlib_MJD(const MJDtime *MJD, int forceJulian, int inner_test_choice, int verbose)
#define TEST04
#define TEST06
#define MJD_1970
int testlib_broken_down_time(int year, int month, int day, int hour, int min, double sec, int forceJulian, int inner_test_choice, int verbose)
#define TEST02
#define TEST01
#define TEST05
#define TEST03
int main()
time_t my_timegm(struct tm *tm)
#define TEST07
double time_sec
Definition qsastimeP.h:20
static char buf[200]
Definition tclAPI.c:873