268 lines
5.6 KiB
C
268 lines
5.6 KiB
C
/* libiso8601/src/tests/leap.c
|
|
*
|
|
* (c)2007, Laurence Withers, <l@lwithers.me.uk>.
|
|
* Released under the GNU GPLv2. See file COPYING or
|
|
* http://www.gnu.org/copyleft/gpl.html for details.
|
|
*/
|
|
|
|
#include "iso8601.h"
|
|
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
|
|
|
|
|
|
int leap_diff(const char* s1, const char* s2, int* diff)
|
|
{
|
|
struct iso8601_date d1, d2;
|
|
|
|
if(iso8601_parse(s1, &d1, 0, 0) || iso8601_parse(s2, &d2, 0, 0)) {
|
|
fprintf(stderr, "Unable to parse ``%s'' or ``%s'' (%m).", s1, s2);
|
|
return -1;
|
|
}
|
|
|
|
*diff = iso8601_leap_elapsed(&d1, &d2);
|
|
return 0;
|
|
}
|
|
|
|
|
|
|
|
int regression1(void)
|
|
{
|
|
struct iso8601_date d;
|
|
char s1[30], s2[30], s3[30];
|
|
int ret = 0, oday;
|
|
|
|
iso8601_from_cal(&d, 2005, 12, 31);
|
|
oday = d.day;
|
|
d.sec = 0;
|
|
d.nsec = 0;
|
|
iso8601_print(s1, sizeof(s1), &d, 0);
|
|
|
|
iso8601_add_seconds(&d, 86400);
|
|
iso8601_print(s2, sizeof(s2), &d, 0);
|
|
ret |= (d.day != oday) | (d.sec != 86400);
|
|
|
|
iso8601_add_seconds(&d, 86400);
|
|
iso8601_print(s3, sizeof(s3), &d, 0);
|
|
ret |= (d.day != (oday + 1)) | (d.sec != 86399);
|
|
|
|
printf("%s -> %s -> %s\n", s1, s2, s3);
|
|
|
|
return ret;
|
|
}
|
|
|
|
|
|
|
|
int regression2(void)
|
|
{
|
|
struct iso8601_date d;
|
|
char s1[30], s2[30], s3[30];
|
|
int ret = 0, oday;
|
|
|
|
iso8601_from_cal(&d, 2005, 12, 31);
|
|
oday = d.day;
|
|
d.sec = 86399;
|
|
d.nsec = 0;
|
|
iso8601_print(s1, sizeof(s1), &d, 0);
|
|
|
|
iso8601_add_seconds(&d, 86400);
|
|
iso8601_print(s2, sizeof(s2), &d, 0);
|
|
ret |= (d.day != (oday + 1)) | (d.sec != 86398);
|
|
|
|
iso8601_add_seconds(&d, 86400);
|
|
iso8601_print(s3, sizeof(s3), &d, 0);
|
|
ret |= (d.day != (oday + 2)) | (d.sec != 86398);
|
|
|
|
printf("%s -> %s -> %s\n", s1, s2, s3);
|
|
|
|
return ret;
|
|
}
|
|
|
|
|
|
|
|
int regression3(void)
|
|
{
|
|
struct iso8601_date d;
|
|
char s1[30], s2[30], s3[30];
|
|
int ret = 0, oday;
|
|
|
|
iso8601_from_cal(&d, 2005, 12, 31);
|
|
oday = d.day;
|
|
d.sec = 86400;
|
|
d.nsec = 0;
|
|
iso8601_print(s1, sizeof(s1), &d, 0);
|
|
|
|
iso8601_add_seconds(&d, 86400);
|
|
iso8601_print(s2, sizeof(s2), &d, 0);
|
|
ret |= (d.day != (oday + 1)) | (d.sec != 86399);
|
|
|
|
iso8601_add_seconds(&d, 86400);
|
|
iso8601_print(s3, sizeof(s3), &d, 0);
|
|
ret |= (d.day != (oday + 2)) | (d.sec != 86399);
|
|
|
|
printf("%s -> %s -> %s\n", s1, s2, s3);
|
|
|
|
return ret;
|
|
}
|
|
|
|
|
|
|
|
int regression4(void)
|
|
{
|
|
struct iso8601_date d;
|
|
char s1[30], s2[30], s3[30];
|
|
int ret = 0, oday;
|
|
|
|
iso8601_from_cal(&d, 2006, 1, 1);
|
|
oday = d.day;
|
|
d.sec = 86399;
|
|
d.nsec = 0;
|
|
iso8601_print(s1, sizeof(s1), &d, 0);
|
|
|
|
iso8601_add_seconds(&d, -86400);
|
|
iso8601_print(s2, sizeof(s2), &d, 0);
|
|
ret |= (d.day != (oday - 1)) | (d.sec != 86400);
|
|
|
|
iso8601_add_seconds(&d, -86400);
|
|
iso8601_print(s3, sizeof(s3), &d, 0);
|
|
ret |= (d.day != (oday - 1)) | (d.sec != 0);
|
|
|
|
printf("%s -> %s -> %s\n", s1, s2, s3);
|
|
|
|
return ret;
|
|
}
|
|
|
|
|
|
|
|
int regression5(void)
|
|
{
|
|
struct iso8601_date d;
|
|
char s1[30], s2[30], s3[30];
|
|
int ret = 0, oday;
|
|
|
|
iso8601_from_cal(&d, 2006, 1, 2);
|
|
oday = d.day;
|
|
d.sec = 86398;
|
|
d.nsec = 0;
|
|
iso8601_print(s1, sizeof(s1), &d, 0);
|
|
|
|
iso8601_add_seconds(&d, -86400);
|
|
iso8601_print(s2, sizeof(s2), &d, 0);
|
|
ret |= (d.day != (oday - 1)) | (d.sec != 86398);
|
|
|
|
iso8601_add_seconds(&d, -86400);
|
|
iso8601_print(s3, sizeof(s3), &d, 0);
|
|
ret |= (d.day != (oday - 2)) | (d.sec != 86399);
|
|
|
|
printf("%s -> %s -> %s\n", s1, s2, s3);
|
|
|
|
return ret;
|
|
}
|
|
|
|
|
|
|
|
int regression6(void)
|
|
{
|
|
struct iso8601_date d;
|
|
char s1[30], s2[30], s3[30];
|
|
int ret = 0, oday;
|
|
|
|
iso8601_from_cal(&d, 2006, 1, 2);
|
|
oday = d.day;
|
|
d.sec = 86399;
|
|
d.nsec = 0;
|
|
iso8601_print(s1, sizeof(s1), &d, 0);
|
|
|
|
iso8601_add_seconds(&d, -86400);
|
|
iso8601_print(s2, sizeof(s2), &d, 0);
|
|
ret |= (d.day != (oday - 1)) | (d.sec != 86399);
|
|
|
|
iso8601_add_seconds(&d, -86400);
|
|
iso8601_print(s3, sizeof(s3), &d, 0);
|
|
ret |= (d.day != (oday - 2)) | (d.sec != 86400);
|
|
|
|
printf("%s -> %s -> %s\n", s1, s2, s3);
|
|
|
|
return ret;
|
|
}
|
|
|
|
|
|
|
|
struct regression_test {
|
|
const char* name;
|
|
int (*func)(void);
|
|
};
|
|
|
|
struct regression_test regression_tests[] = {
|
|
{ "Start of leap day, +86400s", regression1 },
|
|
{ "Near end of leap day, +86400s", regression2 },
|
|
{ "End of leap day, +86400s", regression3 },
|
|
{ "Start of post-leap day, -86400s", regression4 },
|
|
{ "Near end of post-leap day, -86400s", regression5 },
|
|
{ "End of post-leap day, -86400s", regression6 },
|
|
{ 0, 0 }
|
|
};
|
|
|
|
|
|
|
|
int regression(void)
|
|
{
|
|
int ret = 0;
|
|
struct regression_test* test;
|
|
|
|
for(test = regression_tests; test->func; ++test) {
|
|
if(test->func()) {
|
|
fprintf(stderr, "%s failed.\n", test->name);
|
|
++ret;
|
|
}
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
|
|
|
|
int main(int argc, char* argv[])
|
|
{
|
|
int ret = 0, diff;
|
|
|
|
if(argc == 2 && !strcmp(argv[1], "--print-summary")) {
|
|
fputs("Leap second regression test.\n", stdout);
|
|
return 0;
|
|
}
|
|
|
|
switch(argc) {
|
|
case 1:
|
|
ret = regression();
|
|
fputs("Alternative use: pass two dates on commandline to see elapsed leap seconds.\n",
|
|
stdout);
|
|
break;
|
|
|
|
case 3:
|
|
ret = leap_diff(argv[1], argv[2], &diff);
|
|
if(!ret) printf("Leap second correction: %d\n", diff);
|
|
break;
|
|
|
|
case 2:
|
|
if(!strcmp(argv[1], "--print-summary")) {
|
|
printf("Leap second regression test.");
|
|
return 0;
|
|
}
|
|
/* fall through */
|
|
default:
|
|
ret = 1;
|
|
fputs("Either zero or two arguments expected.\n", stderr);
|
|
break;
|
|
}
|
|
|
|
/* TODO */
|
|
|
|
return ret;
|
|
}
|
|
|
|
/* options for text editors
|
|
kate: replace-trailing-space-save true; space-indent true; tab-width 4;
|
|
vim: expandtab:ts=4:sw=4
|
|
*/
|