/* libiso8601/src/tests/calconv.c * * (c)2006, Laurence Withers, . * Released under the GNU GPLv2. See file COPYING or * http://www.gnu.org/copyleft/gpl.html for details. */ #include "iso8601.h" #include #include #include const int _days_in_month_common[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; const int _days_in_month_leap[] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; int try_year(int year) { static int daycount = 0; const int* mc; int m, d, y2, m2, d2, ret = 0; struct iso8601_date dt; mc = iso8601_isleap(year) ? _days_in_month_leap : _days_in_month_common; for(m = 0; m < 12; ++m) { for(d = 0; d < mc[m]; ++d) { if(iso8601_from_cal(&dt, year, m + 1, d + 1)) { ++ret; printf("[cal2date ] %04d-%02d-%02d: %s (%d)\n", year, m + 1, d + 1, strerror(errno), errno); } else if(dt.day != daycount) { ++ret; printf("[discontinuity] %04d-%02d-%02d: got day=%d, expected day=%d\n", year, m + 1, d + 1, dt.day, daycount); } else if(iso8601_to_cal(&y2, &m2, &d2, &dt), year != y2 || m + 1 != m2 || d + 1 != d2) { ++ret; printf("[date2cal ] %04d-%02d-%02d ==> %04d-%02d-%02d (%d)\n", year, m + 1, d + 1, y2, m2, d2, daycount); } ++daycount; } } return ret; } int try_neg_year(int year) { static int daycount = 365; const int* mc; int m, d, y2, m2, d2, ret = 0; struct iso8601_date dt; mc = iso8601_isleap(year) ? _days_in_month_leap : _days_in_month_common; for(m = 11; m >= 0; --m) { for(d = mc[m]; d; --d) { if(iso8601_from_cal(&dt, year, m + 1, d)) { ++ret; printf("[cal2date ] %04d-%02d-%02d: %s (%d)\n", year, m + 1, d, strerror(errno), errno); } else if(dt.day != daycount) { ++ret; printf("[discontinuity] %04d-%02d-%02d: got day=%d, expected day=%d\n", year, m + 1, d, dt.day, daycount); } else if(iso8601_to_cal(&y2, &m2, &d2, &dt), year != y2 || m + 1 != m2 || d != d2) { ++ret; printf("[date2cal ] %04d-%02d-%02d ==> %04d-%02d-%02d (%d)\n", year, m + 1, d, y2, m2, d2, daycount); } --daycount; } } return ret; } // stuff repeats on a 400-year cycle, so we really shouldn't need to worry too much about this #define MAX_YEAR_COUNT 2400 int try_weeks(void) { // starting position int weekcount = 52, weekday = 5, isoyear = -1; int y, wk, wd, ret = 0; struct iso8601_date dt, dt2; for(dt.day = 0; dt.day < MAX_YEAR_COUNT * 366; ++dt.day) { iso8601_to_week(&y, &wk, &wd, &dt); if(wd == 1) { if(weekday != 7) goto discont; ++weekcount; if(wk == 1) { if(weekcount != 53 && weekcount != 54) goto discont; weekcount = 1; ++isoyear; } } if(wk != weekcount || y != isoyear) goto discont; weekday = wd; iso8601_from_week(&dt2, isoyear, weekcount, weekday); if(dt2.day != dt.day) { printf("[weekmismatch ] %04d-W%02d-%d: should be %d, got %d\n", isoyear, weekcount, weekday, dt.day, dt2.day); if(++ret > 20) return ret; } continue; discont: printf("[weekdiscont ] %04d-W%02d-%d ==> %04d-W%02d-%d (%d)\n", isoyear, weekcount, weekday, y, wk, wd, dt.day); isoyear = y; weekcount = wk; weekday = wd; if(++ret > 20) return ret; } return ret; } int main(int argc, char* argv[]) { int ret = 0, year; if(argc == 2 && !strcmp(argv[1], "--print-summary")) { printf("Calendar date / day number conversion test.\n"); return 0; } for(year = 0; year <= MAX_YEAR_COUNT; ++year) { ret += try_year(year); if(ret > 20) return ret; } for(year = 0; year >= -MAX_YEAR_COUNT; --year) { ret += try_neg_year(year); if(ret > 20) return ret; } ret += try_weeks(); if(ret > 20) return ret; return ret; } /* options for text editors kate: replace-trailing-space-save true; space-indent true; tab-width 4; vim: expandtab:ts=4:sw=4 */