#include /* malloc free */ #include /* fprintf */ struct Date { int year; int month; int day; }; /** @param year @return The days in this year. */ int days_year(const int year) { return (!(year % 4) && (year % 100)) || !(year % 400) ? 366 : 365; } /** @param year @param month @return How many days of the month are there. */ int days_month(const int year, const int month) { static const int days_month[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; if(month < 1 || month > 12) return 0; if(month == 2 && days_year(year) == 366) return 29; return days_month[month - 1]; } /** @param str @return Date parsed from str according to ISO rules. */ struct Date parse(const char *str) { struct Date d; int q; q = sscanf(str, "%d-%d-%d", &d.year, &d.month, &d.day); switch(q) { case 0: d.year = 0; case 1: d.month = 1; case 2: d.day = 1; } if(d.month < 1 || d.month > 12) d.month = 1; if(d.day < 1 || d.day > days_month(d.year, d.month)) d.day = 1; /*printf("(%04d-%02d-%02d)\n", d.year, d.month, d.day);*/ return d; } /** @param d Date. @return String. */ char *str_date(const struct Date *d) { static char temp[64]; sprintf(temp, "%04d-%02d-%02d", d->year, d->month, d->day); return temp; } /** @param a @param b @return The number of days between a and b. */ int days(const struct Date *a, const struct Date *b) { int days = 0, i; /* count whole years */ for(i = a->year + 1; i < b->year; i++) { days += days_year(i); /*printf("adding %d days for %d\n", days_year(i), i);*/ } /* count whole months */ if(a->year < b->year) { for(i = a->month + 1; i <= 12; i++) { days += days_month(a->year, i); /*printf("adding %d days for %d-%d\n", days_month(a->year, i), a->year, i);*/ } for(i = 1; i < b->month; i++) { days += days_month(b->year, i); /*printf("adding %d days for %d-%d\n", days_month(b->year, i), b->year, i);*/ } } else { for(i = a->month + 1; i < b->month; i++) { days += days_month(a->year, i); /*printf("adding %d days for %d-%d\n", days_month(i, a->year), a->year, i);*/ } } /* count days */ if(a->year < b->year || a->month < b->month) { days += days_month(a->year, a->month) - a->day + b->day; /*printf("adding %d days\n", days_month(a->year, a->month) - a->day + b->day);*/ } else if(a->day < b->day) { days += b->day - a->day; /*printf("adding %d days\n", b->day - a->day);*/ } return days; } int main(int argc, char **argv) { int num, diff; int isFirst = -1; char str[80]; float ver; struct Date date[2], *d0 = &date[0], *d1 = &date[1], *dt; struct Date base = parse("1996"); *d0 = parse("1996"); *d1 = parse("1996"); while(fscanf(stdin, "%d\t%s\t%f\n", &num, str, &ver) == 3) { dt = d0; d0 = d1; d1 = dt; //printf("num:%d str:%s ver:%f\n", num, str, ver); *d1 = parse(str); if(isFirst) { isFirst = 0; continue; } //printf("Date %d-%d-%d\n", d1->year, d1->month, d1->day); diff = days(d0, d1); //printf("It's %d days after.\n", diff); printf("%d\t%d\t%s\n", days(&base, d1), diff, str_date(d1)); } return EXIT_SUCCESS; }