views:

1698

answers:

7

I am trying to figure out what the day of the week of day zero (January 1st) of a given year.

So far I have looked at the Wikipedia page 'Calculating the day of the week' but I was wondering if there is an easiest algorithm if you're just trying to find day zero.

A: 

The bottom of the Wikipedia page on "Calculating the day of the week" gives the rules you'd need. You could also simplify Zeller's congruence by hardcoding the month and day of the month.

Bill Zeller
+1  A: 

I find this a bit more practical than the article on Wikipedia, but it is still generic:

http://stason.org/TULARC/society/calendars/2-5-What-day-of-the-week-was-2-August-1953.html

cdonner
+6  A: 

Most languages provide facilities for representing and manipulating dates... I would rely on those instead of implementing some (probably incomplete) algorithm.

Zach Scrivena
Assuming "the language" is Standard C, it isn't particularly trivial to make it tell you the day of the week of an arbitrary date. It can be done - it is not particularly simple to do so.
Jonathan Leffler
Good idea if the language has it. Doesn't work worth a hill of beans if you are bootstrapping
BCS
A: 

You could always keep a reference date, and then add days of the year (mod 7) to keep a running tally, but like Zach said, using built-in functions is going to be way easier.

zenazn
You've fotten leap-a-year here. It's 28, not 7, due to this.
Joe Soul-bringer
Actually its a 400 * 7 = 2800 year cycle. See Nikhil's comment on Joe's answer.
j_random_hacker
I meant adding 365 (or 366), then doing mod 7. It's accurate as long as you can predict leap years.
zenazn
@j_random_hacker: Actually, there are exactly (365*400+97)/7 = 20871 weeks in 400 years, so the 400 year cycle repeats exactly without needing to jump to a 2,800 year cycle. If 400 years was not an exact number of weeks, you'd be right.
Jonathan Leffler
@Jonathan: You're right, I stand corrected.
j_random_hacker
A: 

Years repeat on a 28 year cycle. Divide the year by 28 and return the respective day-of-the-week (the day-of-the-week values being stored in an array/vector). This would be the fastest and simplest algorithm. But this algorithm would not be at all clear to someone reading the code. Your choice depends on whether you want fast, simple or "clearly correct".

Joe Soul-bringer
Thanks, that was perfect for what I needed.
Donnie H
(Well, up until 2400)
Eclipse
Yeah, I vaguely remember there's some strange days or other added every once in a while. I suppose we might have a year 2400 problem.
Joe Soul-bringer
Years divisible by 100 are only leap years if they've divisible by 400. Hence 2000 and 2400 are leap years, but 1900 and 2100 aren't.
Nikhil Chelliah
Sorry, have to -1 as I was bitten by the rule Nikhil gave in 2000. Not enough people know the full definition of a leap year!
j_random_hacker
Right - so the 28 year thing will only work until 2100 then (and it worked over 2000 because of the 400 year rule.)
Eclipse
add or subtract floor((year-baseyear)/400) and things should work. I think
BCS
No. try Mark Ransom's algorithm, below. It is intuitive and accurate.
Robert L
+3  A: 

Here's a simple one-liner. I've verified this for all the years 1901-2200 using Excel.

dayOfWeek = (year*365 + trunc((year-1) / 4) - trunc((year-1) / 100) + trunc((year-1) / 400)) % 7

This will give the day of the week as 0=Sunday, 6=Saturday. This result can easily be adjusted by adding a constant before or after the modulus 7.

Mark Ransom
A: 

int dayofweek(y, m, d) /* 0 = Sunday / int y, m, d; / 1 <= m <= 12, y > 1752 or so */ { static int t[] = {0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4}; y -= m < 3; return (y + y/4 - y/100 + y/400 + t[m-1] + d) % 7; }