Advertisement
Guest User

easter.c

a guest
Apr 19th, 2019
90
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 2.50 KB | None | 0 0
  1.  
  2. // easter.c - calculate date of easter
  3. //
  4. // based on https://youtu.be/u7UNEDYN2xY
  5. // "How to Calculate the Date of the Easter Weekend \
  6. //     - Simple Formula - Step by Step Tutorial"
  7. //
  8. // see also:
  9. // http://pubs.opengroup.org/onlinepubs/7908799/xsh/time.h.html
  10. // https://www.timeanddate.com/calendar/determining-easter-date.html
  11. //
  12. // previous: https://pastebin.com/e0QDUfJW
  13. //           https://boards.4channel.org/g/thread/70603712#p70608743
  14. // coding style is still inconsistant...
  15.  
  16. #include <stdio.h>
  17. #include <stdlib.h>
  18. #include <time.h>
  19.  
  20. int main(int argc, char *argv[]) {
  21.     int x, year;
  22.  
  23.     if(argc-1 == 1) {
  24.         x = sscanf(argv[1], "%d", &year);
  25.         if(x == 1) {
  26.             if(year < 32) {
  27.                 puts("easter is under construction...");
  28.                 exit(0);
  29.             }
  30.  
  31.             // unix epoch:        Jan 1st, 1970
  32.             // MS-DOS epoch:      Jan 1st, 1980
  33.             // Common Lisp epoch: Jan 1st, 1900 etc...
  34.  
  35.             if(year < 1970) {
  36.                 puts("unix time routines don't work before 1970");
  37.                 exit(1)
  38.             }
  39.         }
  40.     }
  41.  
  42.     if(argc-1 != 1 || x <= 0) {
  43.         printf("usage: easter <year>\n");
  44.         exit(1);
  45.     }
  46.  
  47.     int metonic = 1 + (year % 19); // lookup table [1..20]
  48.  
  49.     typedef struct { int month; int day; } month_day;
  50.     enum
  51.     {
  52.         Jan=0, Feb, Mar, Apr, May, Jun,
  53.         Jul,   Aug, Sep, Oct, Nov, Dec
  54.     };
  55.  
  56.     month_day table[] = {
  57.         // entry [0] is dummy, end wrap-around
  58.         { Mar, 27 }, { Apr, 14 }, { Apr,  3 }, { Mar, 23 },
  59.         { Apr, 11 }, { Mar, 31 }, { Apr, 18 }, { Apr,  8 },
  60.         { Mar, 28 }, { Apr, 16 }, { Apr,  5 }, { Mar, 25 },
  61.         { Apr, 13 }, { Apr,  2 }, { Mar, 22 }, { Apr, 10 },
  62.         { Mar, 30 }, { Apr, 17 }, { Apr,  7 }, { Mar, 27 }
  63.     };
  64.  
  65.     int month = table[metonic].month;
  66.     int day   = table[metonic].day;
  67.  
  68.     struct tm date;
  69.     date.tm_year = year-1900;
  70.     date.tm_mon  = month;
  71.     date.tm_mday = day;
  72.  
  73.     /* round-trip conversion to fill in day of week */
  74.     time_t t = mktime(&date); localtime_r(&t, &date);
  75.  
  76.     /* can DST or leap year/seconds cause negative weekday? */
  77.     int dow = (date.tm_wday + 7) % 7; // Sun == 0
  78.  
  79.     date.tm_mday += (7-dow);
  80.  
  81.     /* round-trip to fix day of week (and possibly month) */
  82.     t = mktime(&date); localtime_r(&t, &date);
  83.  
  84.     char str[128];
  85.     strftime(str, sizeof(str)-1, "%a, %b %d, %Y", &date);
  86.     printf("%s\n", str);
  87.     return 0;
  88. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement