## Zeller’s Congruence

### October 8, 2010

Zeller’s Congruence is a simple mathematical method for determining the day of the week for a given date.

In the 1880s, Christian Zeller, a German mathematician, noticed that, if you run a year from March through February, the cumulative number of days in each month forms a nearly straight line; that works because February, which would normally perturb the straight line, is moved to the end. He worked out the formula ⌊(13m−1)/5⌋ to give the number of weekdays that the start of the month moves each month, where m is the month number.

Then it is easy to calculate the day of the week for any given day: add the day of the month, the offset for the number of months since March, an offset for each year, and additional offsets for leap years and leap centuries (remembering to subtract one year for dates in January and February), taking the whole thing mod 7. It’s fun to work out the arithmetic yourself, but if you don’t want to take the time, the whole formula is shown in the solution.

Your task is to write a function that uses Zeller’s Congruence to calculate the day of the week for any given date. When you are finished, you are welcome to read or run a suggested solution, or to post your own solution or discuss the exercise in the comments below.

Pages: 1 2

### 5 Responses to “Zeller’s Congruence”

1. […] today’s Programming Praxis exercise, our goal is to implement a function created by Christian Zeller to […]

2. Remco Niemeijer said

```data Weekday = Su | Mo | Tu | We | Th | Fr | Sa deriving (Enum, Eq, Show)

zeller :: Int -> Int -> Int -> Weekday
zeller year month day = toEnum \$ mod (day + div (13 * m - 1) 5 +
d + div d 4 + div c 4 - 2 * c) 7 where
y = if month < 3 then year - 1 else year
m = if month < 3 then month + 10 else month - 2
(c, d) = divMod y 100
```
3. slabounty said
```# f = k + floor(13m - 1) / 5) + d + floor(d / 4) + floor(c / 4) - 2c mod 7

def zeller(year, month, day)
months = %w[march april may june july august september october november december january february]
weekdays = %w[Sunday Monday Tuesday Wednesday Thursday Friday Saturday]
k = day
m = months.index(month.downcase) + 1
y = (m <= 10) ? year : year-1
d = y % 100
c = y / 100
f = (k + (((13*m) - 1) / 5).floor + d + (d/4).floor + (c/4).floor - (2*c)) % 7
weekdays[f]
end

puts zeller(2010, "october", 8)

```
4. Khanh Nguyen said
```open System
open System.Collections.Generic
open Microsoft.FSharp.Collections
open Microsoft.FSharp.Math

(*
*)
let zeller_congruence (year:int) (month:int) (day:int) =
let weekdays = ["Saturday"; "Sunday"; "Monday"; "Tuesday"; "Wednesday"; "Thursday"; "Friday"]
let m = float(if (month < 3) then month + 12 else month)
let y = if (month < 3) then year - 1 else year
let K = float(y % 100)
let J = float(y / 100)
let h = float(day) + floor ((m + 1.0)*26.0 / 10.0 ) + K + floor (K/4.0) + floor(J / 4.0) - 2.0*J

weekdays.[int(h) % 7]

zeller_congruence 2010 10 10
zeller_congruence 2010 2 10
```
5. […] algorithms to calculate the day of the week, one in the Standard Prelude and one in the exercise on Zeller’s Congruence. In today’s exercise we give three more algorithms to calculate the day of the […]