Slik kan det se ut i nettbanken når man får inn en faktura med betalingsfrist på langfredag. SBanken har tydeligvis kontroll på helligdager - og viser at denne først vil bli betalt tirsdag etter påske. Men systemet som produserte fakturaen kunne jo kanskje valgt å sette betalingsfristen til en dag banken har åpent - så slipper jeg som forbruker å forholde meg til dette store dilemmaet.

Hvor vanskelig er det egentlig å implementere støtte for alle offentlige fridager i Norge? Burde ikke dette vært en naturlig del av dato/kalender-håndteringen i alle landets datasystemer?

La oss starte med å se litt på hvilke dager det er snakk om og hvordan disse kan utledes…

Høytidsdager og helligdager i Norge

Det er to offentlige høytidsdager i Norge - 1. mai og 17. mai. Disse er på faste datoer og veldig lett å ta hensyn til.

Også er er det ti helligdager, pluss alle søndager. Av disse ti er tre stykker på faste datoer - 1. januar (nyttårsdag), 25. og 26. desember (1-2. juledag). De andre syv helligdagene settes ut fra påsken (skjærtorsdag, langfredag, 1-2. påskedag, Kristi himmelfartsdag og 1-2. pinsedag).

Så kjapt oppsummert kan man si det slik at den som vet når påsken er lett kan utlede alle offentlige fridager i Norge.

Når er egentlig påsken?

Som vi jo alle lærte da vi var små bestemmes påsken slik:

Første påskedag faller på første søndag etter første fullmåne på eller etter vårjevndøgn.

Så.. Betyr dette at vi må ha en månekyndig astronom ansatt for å utlede når påsken er? Neida - allerede i 1816 publiserte Gauss en formel som finner påskedagen - og i 1876 ble det publisert en formel uten unntak for den gregorianske kalenderen vi bruker (se wikipedia).

Påskeformelen

Formelen er veldig enkel å bruke og kan se slik ut implementert i Clojure:

(defn easter-sunday
  "Compute Easter Sunday given year - using Spencer Jones formula."
  [year]
  (let [a (mod year 19)
        b (quot year 100)
        c (mod year 100)
        d (quot b 4)
        e (mod b 4)
        f (quot (+ b 8) 25)
        g (quot (+ (- b f) 1) 3)
        h (mod (+ (* 19 a) (- b d g) 15) 30)
        i (quot c 4)
        k (mod c 4)
        l (mod (- (+ 32 (* 2 e) (* 2 i)) h k) 7)
        m (quot (+ a (* 11 h) (* 22 l)) 451)
        n (quot (+ h (- l (* 7 m)) 114) 31)
        p (mod (+ h (- l (* 7 m)) 114) 31)]
    {:month n :day (+ p 1)}))

Litt crazy variabel-navn her kanskje, men jeg føler at det passer fint å bruke samme navn som i definisjonen. På wikipedia-artikkelen står implementasjonen i JavaScript - om man liker det bedre enn Clojure.

Alle fridagene

Gitt formelen som finner påskedagen for et år - kan vi lage et lite program som lister opp alle de norske høytids og helligdagene:

(defn find-set-holidays [year]
  #{(date year 1 1)
    (date year 5 1)
    (date year 5 17)
    (date year 12 25)
    (date year 12 26)})

(defn find-variable-holidays [year]
  (let [esMap (easter-sunday year)
        eDay (date year (:month esMap) (:day esMap))]
    #{(.minusDays eDay 7)
      (.minusDays eDay 3)
      (.minusDays eDay 2)
      eDay
      (.plusDays eDay 1)
      (.plusDays eDay 39)
      (.plusDays eDay 49)
      (.plusDays eDay 50)}))

(defn find-holidays [year]
  (union (find-set-holidays year) (find-variable-holidays year)))

Og da er det jo lett å utvide med funksjoner for å sjekke om en gitt dato er helligdag. Eller kanskje legge til 10 arbeidsdager for å finne en betalingsfrist om to uker som ikke er en helligdag eller helg.

Biblioteker

Dette er jo veldig lett å implementere selv. Om man skulle ønske å få ferdig kode har jeg laget Clojure-biblioteker for å finne påskedagen og hjelpefunksjoner for datohåndtering:

For mange år siden lagde jeg det samme i Java - tilgjengelig på BEKK sitt nocommons open source bibliotek:

Så enkelt - og veldig nyttig. Regner med alle får dette på plass de neste ukene - så jeg slipper å forholde meg til umulige datoer i nettbanken min :)