feat: generate 2026-2040 liturgical calendar
Co-authored-by: rafa <rcalvotorrejon@gmail.com> Signed-off-by: rafa <rcalvotorrejon@gmail.com>
This commit is contained in:
@@ -0,0 +1,71 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Generate the reviewable civil-date lookup used by the daily Gospel shortcode.
|
||||
|
||||
Sources: CEE, "Tabla temporal de las principales celebraciones del Año
|
||||
Litúrgico 2021-2044"; Normas Universales sobre el Año litúrgico.
|
||||
"""
|
||||
from datetime import date, timedelta
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
WEEKDAYS = ["monday", "tuesday", "wednesday", "thursday", "friday", "saturday", "sunday"]
|
||||
|
||||
def easter(year):
|
||||
a=year%19; b=year//100; c=year%100; d=b//4; e=b%4; f=(b+8)//25; g=(b-f+1)//3
|
||||
h=(19*a+b-d-g+15)%30; i=c//4; k=c%4; l=(32+2*e+2*i-h-k)%7; m=(a+11*h+22*l)//451
|
||||
return date(year,(h+l-7*m+114)//31,(h+l-7*m+114)%31+1)
|
||||
|
||||
def advent(year):
|
||||
# Sunday falling from 27 November through 3 December.
|
||||
d=date(year,11,27)
|
||||
return d+timedelta(days=(6-d.weekday())%7)
|
||||
|
||||
def cycle(d):
|
||||
start=d.year+1 if d>=advent(d.year) else d.year
|
||||
return "ABC"[(start-2026)%3]
|
||||
|
||||
def special(d, pascha):
|
||||
fixed={(1,1):"mary-mother",(1,6):"epiphany",(2,2):"presentation",
|
||||
(3,19):"joseph",(3,25):"annunciation",(6,24):"john-baptist",
|
||||
(6,29):"peter-paul",(7,22):"magdalene",(7,25):"james",
|
||||
(8,6):"transfiguration",(8,15):"assumption",(11,1):"all-saints",
|
||||
(11,2):"all-souls",(12,8):"immaculate",(12,25):"christmas"}
|
||||
if (d.month,d.day) in fixed: return fixed[(d.month,d.day)]
|
||||
offsets={-46:"ash-wednesday",-7:"palm-sunday",-3:"holy-thursday",-2:"good-friday",
|
||||
0:"easter-sunday",1:"easter-monday",49:"pentecost",56:"trinity",60:"corpus-christi"}
|
||||
return offsets.get((d-pascha).days)
|
||||
|
||||
def liturgical_day(d):
|
||||
p=easter(d.year); a_this=advent(d.year); a_prev=advent(d.year-1)
|
||||
sp=special(d,p)
|
||||
if sp: return sp
|
||||
if d>=a_this: return f"advent-{((d-a_this).days//7)+1}-{WEEKDAYS[d.weekday()]}"
|
||||
# Christmas starts on the previous Advent's Dec 25 and runs through Baptism.
|
||||
baptism=date(d.year,1,6)+timedelta(days=(6-date(d.year,1,6).weekday())%7 or 7)
|
||||
if (d.month == 12 and d.day >= 25) or (d.month == 1 and d <= baptism):
|
||||
return f"christmas-{WEEKDAYS[d.weekday()]}"
|
||||
ash=p-timedelta(days=46)
|
||||
if ash<=d<p:
|
||||
return f"lent-{max(0,(d-ash).days//7)}-{WEEKDAYS[d.weekday()]}"
|
||||
if p<d<=p+timedelta(days=49):
|
||||
return f"easter-{((d-p).days-1)//7+1}-{WEEKDAYS[d.weekday()]}"
|
||||
if d<ash:
|
||||
first=baptism+timedelta(days=1)
|
||||
return f"ordinary-{((d-first).days//7)+1}-{WEEKDAYS[d.weekday()]}"
|
||||
# Number the resumed Ordinary Time backwards from the 34th week.
|
||||
last_sunday=a_this-timedelta(days=7)
|
||||
sunday=d+timedelta(days=(6-d.weekday())%7)
|
||||
sunday_number=34-((last_sunday-sunday).days//7)
|
||||
return f"ordinary-{sunday_number-1}-{WEEKDAYS[d.weekday()]}"
|
||||
|
||||
def main():
|
||||
out={"schema":1,"range":{"from":"2026-01-01","to":"2040-12-31"},
|
||||
"sources":["https://www.conferenciaepiscopal.es/tabla-temporal-celebraciones-ano-liturgico-2021-2044/"],"dates":{}}
|
||||
d=date(2026,1,1); end=date(2040,12,31)
|
||||
while d<=end:
|
||||
out["dates"][d.isoformat()]={"key":liturgical_day(d),"cycle":cycle(d)}
|
||||
d+=timedelta(days=1)
|
||||
path=Path("data/evangelio-diario/calendario-liturgico-2026-2040.json")
|
||||
path.write_text(json.dumps(out,ensure_ascii=False,indent=2)+"\n",encoding="utf-8")
|
||||
print(f"wrote {len(out['dates'])} dates")
|
||||
if __name__=="__main__": main()
|
||||
Reference in New Issue
Block a user