/* Copyright (c) 2008 Anonymous * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that you grant this * same permission to anyone you distribute it to without any additional * restrictions. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include #include #include #include #include #include int main(int argc, char **argv){ uintmax_t year = 0; uintmax_t month = 0; int_fast8_t month_days = 0, day_of_week = 0; const char *month_names[12] = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" }; const int_fast8_t months_days[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; time_t t = time(NULL); struct tm *time_struct = localtime(&t); switch(argc){ case 1: year = time_struct->tm_year + 1900; month = time_struct->tm_mon + 1; break; case 2: year = strtoumax(argv[1], NULL, 10); month = time_struct->tm_mon + 1; break; default: month = strtoumax(argv[1], NULL, 10); year = strtoumax(argv[2], NULL, 10); } if(!year || !month || month > 12){ fputs("learn to use cal, you idiot: http://opengroup.org/susv3xcu/cal.html\n", stderr); abort(); } #ifndef OVER_9999 if(year > 9999){ fputs("learn to use cal, you idiot: http://opengroup.org/susv3xcu/cal.html\n", stderr); abort(); } #endif if(year == 1752 && month == 9){ puts("September 1752"); puts("Su Mo Tu We Th Fr Sa"); puts(" 1 2 14 15 16"); puts("17 18 19 20 21 22 23"); puts("24 25 26 27 28 29 30"); return 0; }else{ printf("%s %" PRIuMAX "\n", month_names[month - 1], year); puts("Su Mo Tu We Th Fr Sa"); month_days = months_days[month - 1]; if(year > 1752 || (year == 1752 && month > 9)){ /* Gregorian */ if(month == 2 && !(year % 4) && year % 100 || !(year % 400)) month_days = 29; day_of_week = ((153 * (month + 12 * ((14 - month) / 12) - 3) + 2) / 5 + 365 * (year + 4800 - ((14 - month) / 12)) + (year + 4800 - ((14 - month) / 12)) / 4 - (year + 4800 - ((14 - month) / 12)) / 100 + (year + 4800 - ((14 - month) / 12)) / 400 - 32043) % 7; }else{ /* Julian */ if(month == 2 && !(year % 4)) month_days = 29; day_of_week = ((153 * (month + 12 * ((14 - month) / 12) - 3) + 2) / 5 + 365 * (year + 4800 - ((14 - month) / 12)) + (year + 4800 - ((14 - month) / 12)) / 4 - 32081) % 7; } for(int i = 0; i < day_of_week; ++i) fputs(" ", stdout); for(int i = 1; i <= month_days; ++i){ printf("% 2u", i); ++day_of_week; putchar((day_of_week %= 7) ? ' ' : '\n'); } } putchar('\n'); return 0; }