#include #include #define HELP_STR "usage: name year [month] day" int month_day(int year, int day, int *pmonth); int day_of_year(int year, int month, int day); /* converts arguments year yearday to year month day or * year month day to year yearday */ int main(int argc, char *argv[]) { int y, m, d, yd; if (argc == 3) { /* year day -> month day */ y = atoi(argv[1]), yd = atoi(argv[2]); if ((d = month_day(y, yd, &m))) { printf("%d %d %d\n", y, m, d); return 0; } printf("error: invalid yearday %d\n", yd); } else if (argc == 4) { /* year month day -> year day */ y = atoi(argv[1]), m = atoi(argv[2]), d = atoi(argv[3]); if ((yd = day_of_year(y, m, d))) { printf("%d %d\n", y, yd); return 0; } printf("error: invalid month %d or day %d\n", m, d); } puts(HELP_STR); return 1; } static char daytab[][13] = { {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} }; #define IS_LEAP(Y) (Y%4 == 0 && Y%100 != 0 || Y%400 == 0) #define IS_MONTH(M) (0 < M && M <= 12) #define IS_D_OF_M(LEAP, M, D) (0 < D && D <= daytab[LEAP][M]) #define IS_YD_OF_Y(LEAP, YD) (0 < YD && YD <= 365+LEAP) /* day_of_year: set day of year from month & day * return day of year or 0 on error */ int day_of_year(int year, int month, int day) { int m, leap = IS_LEAP(year); if (!IS_MONTH(month) || !IS_D_OF_M(leap, month, day)) /* validity check */ return 0; for (m = 1; m < month; m++) day += daytab[leap][m]; return day; } /* month_day: set month, day from day of year * return day of month or 0 on error, set pmonth to month */ int month_day(int year, int yearday, int *pmonth) { int m, leap = IS_LEAP(year); if (!IS_YD_OF_Y(leap, yearday)) /* validity check */ return 0; for (m = 1; yearday > daytab[leap][m]; m++) yearday -= daytab[leap][m]; *pmonth = m; return yearday; }