from datetime import date, timedelta

EPOCH = date(1980, 1, 6)
def week(d): return (d - EPOCH).days // 7
def day_of(w, dow=0): return EPOCH + timedelta(weeks=w, days=dow)

outage = date(2026, 7, 8)
T = week(outage); dow = (outage - EPOCH).days % 7
print("outage", outage, outage.strftime("%A"), "GPS week", T, "broadcast 10-bit week", T % 1024, "epoch #", T // 1024)
back = outage - timedelta(weeks=1024)
print("outage - 1024 weeks =", back, back.strftime("%A"), "(7168 days)")
print("1024 weeks in years: %.4f (365.2425-day years), %.4f (365.25)" % (7168 / 365.2425, 7168 / 365.25))
for name, d in [("1st rollover", day_of(1024)), ("2nd rollover", day_of(2048)), ("3rd rollover", day_of(3072))]:
    print(name, d, "week", week(d))
ro = date(2022, 9, 18)
W = week(ro); W0 = W - 1024
print("Chronos rollover", ro, ro.strftime("%A"), "= GPS week", W, "| implied window start", day_of(W0), "(week %d)" % W0)
print("a window [%s, %s) maps %s -> %s : in window? %s" % (day_of(W0), ro, outage, back, day_of(W0) <= back < ro))
print("days the card spent past its window before the reset:", (outage - ro).days, "| GPS card connected Oct 2025 (TAP p.3):",
      "after the window closed" if date(2025, 10, 1) > ro else "before")
step = 1024 * 7 * 86400
print("clock step: %d s = %.0f x RFC 5905's panic threshold PANICT (1000 s; s.11.3 Fig. 27, p.49)" % (step, step / 1000))
oct25 = date(2025, 10, 1)
print("Chronos rollover -> GPS card made the Melbourne source (Oct 2025, TAP p.3): about %d days (%.1f years)"
      % ((oct25 - ro).days, (oct25 - ro).days / 365.2425))
