libiso8601/src/tests/leap.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
*/