diff --git a/wizard-work/beam/zeller_dow.py b/wizard-work/beam/zeller_dow.py new file mode 100644 index 0000000..98e908a --- /dev/null +++ b/wizard-work/beam/zeller_dow.py @@ -0,0 +1,38 @@ +"""Day-of-week via Julian Day Number, handling Julian/Gregorian transition. + +Dates before 1582-10-15 use the Julian calendar; on/after use Gregorian. +The gap 1582-10-05..14 did not exist. +""" +def _jdn_julian(y, m, d): + a = (14 - m) // 12 + yy = y + 4800 - a + mm = m + 12 * a - 3 + return d + (153 * mm + 2) // 5 + 365 * yy + yy // 4 - 32083 + +def _jdn_gregorian(y, m, d): + a = (14 - m) // 12 + yy = y + 4800 - a + mm = m + 12 * a - 3 + return d + (153 * mm + 2) // 5 + 365 * yy + yy // 4 - yy // 100 + yy // 400 - 32045 + +NAMES = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"] + +def dow(y, m, d): + if not (1 <= m <= 12 and 1 <= d <= 31): + raise ValueError("invalid month/day") + if (y, m, d) < (1582, 10, 15): + jdn = _jdn_julian(y, m, d) + else: + jdn = _jdn_gregorian(y, m, d) + return NAMES[jdn % 7] + +def main(): + import sys + if len(sys.argv) != 4: + print("usage: zeller_dow.py YYYY MM DD"); return 2 + y, m, d = int(sys.argv[1]), int(sys.argv[2]), int(sys.argv[3]) + print(dow(y, m, d)) + return 0 + +if __name__ == "__main__": + raise SystemExit(main())