/* daymath.c * * The author places the following code in the public domain. * * Contact: Andy Goth * * For useful information on dates and calendars, visit * */ #include #include /* Returns true if and only iff [y-m-d] is a valid date. */ static int dayvalidate (int y, int m, int d) { int length[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; /* Months must be in the range [1..12]. */ if (m < 1 || m > 12) { return 0; } /* Years must be AD. */ if (y < 1) { return 0; } /* Days must be within the month. Allow Feb 29 for leap years. */ if (d < 1 || (d > length[m - 1] && (m != 2 || d != 29 || y % 4 != 0 || (y % 100 == 0 && y % 400 != 0)))) { return 0; } /* Valid. */ return 1; } /* Returns the number of days between [y-m-d] and [2000-01-01]. Positive * indicates [y-m-d] occurs after [2000-01-01]. */ static int daycount (int y, int m, int d) { /* Treat January and February as extensions to the previous year, * as in Zeller's congruence. */ if (m < 3) { m += 12; y -= 1; } return -730517 /* Constant gives base date 2000-01-01 AD. */ + d /* Start with the day of the month. */ + ((153 * m - 2) / 5) /* Add the beginning of the month. */ + 365 * y /* Most years are 365 days in length, */ + (y / 4) /* but every fourth year has an extra day, */ - (y / 100) /* except for every hundredth year */ + (y / 400); /* that isn't a multiple of 400. */ } /* Returns the number of days between [y1-m1-d1] and [y2-m2-d2]. Positive * indicates [y1-m1-d1] occurs after [y2-m2-d2]. */ static int daydifference (int y1, int m1, int d1, int y2, int m2, int d2) { return daycount(y1, m1, d1) - daycount(y2, m2, d2); } int main(int argc, char** argv) { int args[6]; int i; int count; char* end; /* Check for correct number of arguments. */ if (argc != 7) { fprintf(stderr, "Usage: %s YYYY MM DD YYYY MM DD\n", argv[0]); return EXIT_FAILURE; } /* Get integers from command-line arguments. */ for (i = 0; i < 6; ++i) { args[i] = strtol(argv[i + 1], &end, 10); if (argv[i + 1][0] == '\0' || end[0] != '\0') { fprintf(stderr, "Bad integer \"%s\"\n", argv[i + 1]); return EXIT_FAILURE; } } /* Check validity of dates. */ for (i = 0; i < 6; i += 3) { if (!dayvalidate(args[i + 0], args[i + 1], args[i + 2])) { fprintf(stderr, "Bad date [%04d-%02d-%02d]\n", args[i + 0], args[i + 1], args[i + 2]); return EXIT_FAILURE; } } /* Do it! */ count = abs(daycount(args[0], args[1], args[2]) - daycount(args[3], args[4], args[5])) + 1; printf("Number of days in range [%04d-%02d-%02d] - [%04d-%02d-%02d]: %d \n", args[0], args[1], args[2], args[3], args[4], args[5], count); /* Done. */ return EXIT_SUCCESS; } /* vim: set ts=4 sts=4 sw=4 tw=80 et: */