/* * month() picks apart a month specification * * /[<month> NUMBER [NUMBER]] \ * |[TOMORROW] | * |[DAY OF WEEK] | * |NUMBER [SLASH NUMBER [SLASH NUMBER]]| * \PLUS NUMBER MINUTES|HOURS|DAYS|WEEKS/ */ static void month(struct tm *tm) { long year= (-1); long mday = 0, wday, mon; int tlen; switch (sc_tokid) { case PLUS: plus(tm); break; case TOMORROW: /* do something tomorrow */ tm->tm_mday ++; tm->tm_wday ++; case TODAY: /* force ourselves to stay in today - no further processing */ token(); break; case JAN: case FEB: case MAR: case APR: case MAY: case JUN: case JUL: case AUG: case SEP: case OCT: case NOV: case DEC: /* do month mday [,year] */ mon = (sc_tokid-JAN); expect(NUMBER); mday = atol(sc_token); if (token() == COMMA) { if (token() == NUMBER) { year = atol(sc_token); token(); } } assign_date(tm, mday, mon, year); if (sc_tokid == PLUS) plus(tm); break; case SUN: case MON: case TUE: case WED: case THU: case FRI: case SAT: /* do a particular day of the week */ wday = (sc_tokid-SUN); mday = tm->tm_mday; /* if this day is < today, then roll to next week */ if (wday < tm->tm_wday) mday += 7 - (tm->tm_wday - wday); else mday += (wday - tm->tm_wday); tm->tm_wday = wday; assign_date(tm, mday, tm->tm_mon, tm->tm_year); break; case NUMBER: /* get numeric MMDDYY, mm/dd/yy, or dd.mm.yy */ tlen = strlen(sc_token); mon = atol(sc_token); token(); if (sc_tokid == SLASH || sc_tokid == DOT) { int sep; sep = sc_tokid; expect(NUMBER); mday = atol(sc_token); if (token() == sep) { expect(NUMBER); year = atol(sc_token); token(); } /* flip months and days for European timing */ if (sep == DOT) { int x = mday; mday = mon; mon = x; } } else if (tlen == 6 || tlen == 8) { if (tlen == 8) { year = (mon % 10000) - TM_YEAR_BASE; mon /= 10000; } else { year = mon % 100; mon /= 100; } mday = mon % 100; mon /= 100; } else panic("garbled time"); mon--; if (mon < 0 || mon > 11 || mday < 1 || mday > 31) panic("garbled time"); assign_date(tm, mday, mon, year); break; } /* case */ } /* month */
END_TEST START_TEST(test_cal_interval) { date_t d1, d2; int interval; init_date(&d1); init_date(&d2); assign_date(&d1, 2012, 2, 20); assign_date(&d2, 2012, 3, 20); aunt_date_cal_interval(&interval, &d1, &d2); fail_unless((interval == 29), "calculate interval between" "(%04d-%02d-%02d) and (%04d-%02d-%02d) uncorrectly", d1.year, d1.month, d1.day, d1.year, d1.month, d1.day); assign_date(&d1, 2012, 3, 20); assign_date(&d2, 2012, 2, 20); aunt_date_cal_interval(&interval, &d1, &d2); fail_unless((interval == 29), "calculate interval between" "(%04d-%02d-%02d) and (%04d-%02d-%02d) uncorrectly", d1.year, d1.month, d1.day, d1.year, d1.month, d1.day); assign_date(&d1, 2013, 2, 20); assign_date(&d2, 2013, 3, 20); aunt_date_cal_interval(&interval, &d1, &d2); fail_unless((interval == 28), "calculate interval between" "(%04d-%02d-%02d) and (%04d-%02d-%02d) uncorrectly", d1.year, d1.month, d1.day, d1.year, d1.month, d1.day); assign_date(&d1, 2013, 3, 20); assign_date(&d2, 2013, 2, 20); aunt_date_cal_interval(&interval, &d1, &d2); fail_unless((interval == 28), "calculate interval between" "(%04d-%02d-%02d) and (%04d-%02d-%02d) uncorrectly", d1.year, d1.month, d1.day, d1.year, d1.month, d1.day); assign_date(&d1, 2012, 2, 1); assign_date(&d2, 2012, 2, 28); aunt_date_cal_interval(&interval, &d1, &d2); fail_unless((interval == 27), "calculate interval between" "(%04d-%02d-%02d) and (%04d-%02d-%02d) uncorrectly", d1.year, d1.month, d1.day, d1.year, d1.month, d1.day); assign_date(&d1, 2012, 2, 28); assign_date(&d2, 2012, 2, 1); aunt_date_cal_interval(&interval, &d1, &d2); fail_unless((interval == 27), "calculate interval between" "(%04d-%02d-%02d) and (%04d-%02d-%02d) uncorrectly", d1.year, d1.month, d1.day, d1.year, d1.month, d1.day); assign_date(&d1, 2012, 12, 15); assign_date(&d2, 2013, 1, 16); aunt_date_cal_interval(&interval, &d1, &d2); fail_unless((interval == 32), "calculate interval between" "(%04d-%02d-%02d) and (%04d-%02d-%02d) uncorrectly", d1.year, d1.month, d1.day, d1.year, d1.month, d1.day); assign_date(&d1, 2013, 1, 15); assign_date(&d2, 2012, 12, 16); aunt_date_cal_interval(&interval, &d1, &d2); fail_unless((interval == 30), "calculate interval between" "(%04d-%02d-%02d) and (%04d-%02d-%02d) uncorrectly", d1.year, d1.month, d1.day, d1.year, d1.month, d1.day); }
/* * month() picks apart a month specification * * /[<month> NUMBER [NUMBER]] \ * |[TOMORROW] | * |[DAY OF WEEK] | * |NUMBER [SLASH NUMBER [SLASH NUMBER]]| * \PLUS NUMBER MINUTES|HOURS|DAYS|WEEKS/ */ static void month(struct tm *tm) { int year; int mday, wday, mon; size_t tlen; year = -1; mday = 0; switch (sc_tokid) { case PLUS: plus(tm); break; case TOMORROW: /* do something tomorrow */ tm->tm_mday++; tm->tm_wday++; /*FALLTHROUGH*/ case TODAY: /* force ourselves to stay in today - no further processing */ (void)token(); break; case JAN: case FEB: case MAR: case APR: case MAY: case JUN: case JUL: case AUG: case SEP: case OCT: case NOV: case DEC: /* * do month mday [year] */ mon = sc_tokid - JAN; expect(NUMBER); mday = atoi(sc_token); if (token() == NUMBER) { year = atoi(sc_token); (void)token(); } assign_date(tm, mday, mon, year); break; case SUN: case MON: case TUE: case WED: case THU: case FRI: case SAT: /* do a particular day of the week */ wday = sc_tokid - SUN; mday = tm->tm_mday; /* if this day is < today, then roll to next week */ if (wday < tm->tm_wday) mday += 7 - (tm->tm_wday - wday); else mday += (wday - tm->tm_wday); tm->tm_wday = wday; assign_date(tm, mday, tm->tm_mon, tm->tm_year + TM_YEAR_BASE); break; case NUMBER: /* * get numeric MMDDYY, mm/dd/yy, or dd.mm.yy */ tlen = strlen(sc_token); mon = atoi(sc_token); (void)token(); if (sc_tokid == SLASH || sc_tokid == DOT) { tokid_t sep; sep = sc_tokid; expect(NUMBER); mday = atoi(sc_token); if (token() == sep) { expect(NUMBER); year = atoi(sc_token); (void)token(); } /* * flip months and days for european timing */ if (sep == DOT) { int x = mday; mday = mon; mon = x; } } else if (tlen == 6 || tlen == 8) { if (tlen == 8) { year = (mon % 10000) - 1900; mon /= 10000; } else { year = mon % 100; mon /= 100; } mday = mon % 100; mon /= 100; } else panic("garbled time"); mon--; if (mon < 0 || mon > 11 || mday < 1 || mday > 31) panic("garbled time"); assign_date(tm, mday, mon, year); break; default: /* plonk(sc_tokid); */ /* XXX - die here? */ break; } }