mothering_sunday_ical/main.go
2026-02-06 09:56:03 +00:00

74 lines
1.4 KiB
Go

package main
import (
"fmt"
"log"
"os"
"time"
ics "github.com/arran4/golang-ical"
)
func motheringSunday(year int) (time.Time, error) {
// Calculate Easter Sunday
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
month := time.Month(h+l-7*m+114) / 31
day := ((h + l - 7*m + 114) % 31) + 1
easterSunday := time.Date(year, month, day, 0, 0, 0, 0, time.UTC)
// Calculate Mothering Sunday
mothersDay := easterSunday.AddDate(0, 0, -21) // Add 21 days (3 weeks)
if mothersDay.Weekday() != 0 {
return time.Time{}, fmt.Errorf("Code generated a non-Sunday")
}
return mothersDay, nil
}
func generateIcal() (string, error) {
prodId := "sh.wallace.scott.motheringSunday"
cal := ics.NewCalendar()
cal.SetProductId(prodId)
thisYear := time.Now().Year()
for year := thisYear; year < thisYear+10; year++ {
ms, err := motheringSunday(year)
if err != nil {
return "", err
}
event := cal.AddEvent(fmt.Sprintf("%d@%s", ms.Unix(), prodId))
event.SetSummary("Mothering Sunday")
event.SetAllDayStartAt(ms)
}
return cal.Serialize(), nil
}
func main() {
ical, err := generateIcal()
if err != nil {
log.Panic(err)
}
f, err := os.Create("mothering_sunday.ics")
if err != nil {
log.Panic(err)
}
defer f.Close()
f.Write([]byte(ical))
}