
Day of Week Algorithm - ltcode
https://www.programmingalgorithms.com/algorithm/day-of-week
======
cokernel
This algorithm didn't appear out of nowhere. Maybe this page should mention
the source?

I had pictured this as being essentially Gauss's algorithm, but if Wikipedia
is correct, this particular implementation is due to Tomohiko Sakamoto in
1993.

[https://en.wikipedia.org/wiki/Determination_of_the_day_of_th...](https://en.wikipedia.org/wiki/Determination_of_the_day_of_the_week#Implementation-
dependent_methods)

~~~
mxuribe
Agreed, source of algorithms would be cool to include for these...but still, i
think its pretty cool concept to have such a website.

Anyone know of other, similar websites but for python? Or even if not for
python, just another website like this.

~~~
cokernel
Does Rosetta Code count?

~~~
mxuribe
Rosetta code is awesome! I especially like the "Similar Sites" page
<[http://rosettacode.org/wiki/Help:Similar_Sites>](http://rosettacode.org/wiki/Help:Similar_Sites>)

Thanks @cokernel!

------
chris_overseas
Here's some code I wrote years ago using a different algorithm called Zeller's
Congruence[1]. The advantage of this is it doesn't require a lookup table:

    
    
      public int dayOfWeek(int year, int month, int day) {
        day += month < 3 ? year-- : year - 2;
        return ((((23 * month) / 9) + day + 4 + (year / 4)) - (year / 100) + (year / 400)) % 7;
      }
    

[1]
[https://en.wikipedia.org/wiki/Zeller%27s_congruence](https://en.wikipedia.org/wiki/Zeller%27s_congruence)

~~~
imaginenore
I'm pretty sure the post's solution is wrong.

Examples:

2008-06-11 (Wednesday). Post's function returns 2 instead of 3.

~~~
pveierland
When inputting day of month in range [1,31] and month in range [1,12] the
function seems to work fine. Verified here from 1900-01-01 through 2020-01-01:

[http://ideone.com/te3ywm](http://ideone.com/te3ywm)

------
darfs
Nice Page!

But, in my opinion, it would be nice to know "why". Sure, i can digg into it,
spend a day to understand or can use Google to find the answer; But it would
be awesome if they will provide that information on the pages to the
algorithms.

I.e the SHA 256 Page: I really like it. But if i'm new in this field, and
don't even know about it a simple Wikipedia link would be enough to give me an
"introduction" to the Algorithm. And, without it: It stays nice :)

------
Daneel_
All this discussion, and I'm over here simply being mock-annoyed that Sunday
is being listed as the first day of the week.

I know it's a personal choice, but why do some people think the week starts on
a Sunday? I'm curious as to what the explanation is?

~~~
DanBC
The bible says saturday is the last day of the week, which means societies
with a strong christian tradition use sunday as the start of the week.

Sunday is defined in law as the start of the week in some bits of English law,
so there's that.

~~~
loopbit
I don't think that's right, do you have any links?

Italy, Spain, Ireland, England... actually all european countries (AFAIK) use
Monday as the start of the week. All countries with a strong christian
tradition.

The only countries I know that use Sunday as the start of the week are the US
and Israel.

A quick search in wikipedia[0] also mentions that it's used as the first day
of the week in Hebrew tradition and in some muslim countries.

[0]
[https://en.wikipedia.org/wiki/Sunday#Position_in_the_week](https://en.wikipedia.org/wiki/Sunday#Position_in_the_week)

~~~
DanBC
Traditionally England does not use Monday as the start of the week. This is
easy to see if you look at older calendars.

At the moment there's some inconsistancy:

Sunday to Saturday: [https://www.gov.uk/maternity-pay-
leave/pay](https://www.gov.uk/maternity-pay-leave/pay)

Monday to Sunday: [https://www.gov.uk/guidance/statutory-sick-pay-manually-
calc...](https://www.gov.uk/guidance/statutory-sick-pay-manually-calculate-
your-employees-payments)

Googling for ["sunday to saturday" inurl:gov.uk] or ["monday to sunday"
inurl:gov.uk] shows a bunch of examplesof each.

EDIT: You asked for links, so here's something from 2009 asking why it's so
hard to find a calendar that starts on a monday:
[http://www.theguardian.com/notesandqueries/query/0,,-200944,...](http://www.theguardian.com/notesandqueries/query/0,,-200944,00.html)

> Why is it so hard to find a calendar that starts the week on a Monday, not a
> Sunday? It can't just be my family who gets outraged by this.

And here's something else from 2009 which (weirdly) explaining why it's so
hard to find calendars that start on Sunday, not Monday.

[http://www.telegraph.co.uk/comment/letters/6495398/Officiall...](http://www.telegraph.co.uk/comment/letters/6495398/Officially-
Sunday-is-not-the-first-day-of-the-week.html)

tl;dr England used Sunday as the first day of the week until they started
using ISO standards for time.

------
curiousCitizen
I wonder, is this more efficient than Microsoft's implementation?

    
    
       DateTime.Today.DayOfWeek;
    
       public DayOfWeek DayOfWeek {
                get {
                    Contract.Ensures(Contract.Result<DayOfWeek>() >= DayOfWeek.Sunday);
                    Contract.Ensures(Contract.Result<DayOfWeek>() <= DayOfWeek.Saturday);
                    return (DayOfWeek)((InternalTicks / TicksPerDay + 1) % 7);
                }
            }
    
        public enum DayOfWeek {
            Sunday = 0,
            Monday = 1,
            Tuesday = 2,
            Wednesday = 3,
            Thursday = 4,
            Friday = 5,
            Saturday = 6,
        }
    
    

[http://referencesource.microsoft.com/#mscorlib/system/dateti...](http://referencesource.microsoft.com/#mscorlib/system/datetime.cs,f6ea9c9a0d4b5e43)
[http://referencesource.microsoft.com/#mscorlib/system/dayofw...](http://referencesource.microsoft.com/#mscorlib/system/dayofweek.cs)

~~~
Someone
That's a different problem; it doesn't take year/month/day, but
_InternalTicks_ (and, nitpicking, doesn't appear to handle leap seconds, an
issue that doesn't exist for functions taking ymd as input)

~~~
masklinn
It's a different implementation, not a different concept. InternalTicks are
how datetime data is represented in a C# datetime object (actually dateData
which is a 64b bitfield: the first 62 bits are the internal tick, the last 2
bits are the kind).

~~~
mark-r
So all the hard work of converting year/month/day to InternalTicks is done at
creation time, greatly simplifying the weekday calculation occurring later.

------
codemaniac
In Python:

[https://repl.it/B6os/5](https://repl.it/B6os/5)

~~~
masklinn
Why would you bother with that when you can just call `date.strftime("%A")`?
(or `date.isoweekday()` if you want the numerical index)

------
TheAndruu
This is real easy in Java:

    
    
        private DayOfWeek getDayOfWeek(int year, int month, int day) {
            return LocalDate.of(year, month, day).getDayOfWeek();
        }
    
        @Test
        public void getDayOfWeekTest() {
            assertEquals(DayOfWeek.FRIDAY, getDayOfWeek(2016, 3, 25));
        }
    

It's a built-in function in Java 8. Under the hood, one can see what it's
doing is converting the given date to an `EpochDay`, taking the `floorMod` of
that by 7, and then returning the index of the DayOfWeek enum. Basically:

    
    
        public enum DayOfWeek { MONDAY, TUESDAY... }
    
        int dow0 = (int)Math.floorMod(toEpochDay() + 3, 7);
        return ENUMS[dayOfWeek - 1];

~~~
vr3690
Wonder why you were downvoted

------
kej
If you want to do it in your head, there's Conway's Doomsday Rule:
[https://en.wikipedia.org/wiki/Doomsday_rule](https://en.wikipedia.org/wiki/Doomsday_rule)

------
great_kraken
Here's how it's implemented in Ruby:

    
    
      static int
      calc_wday(int year, int month, int day)
      {
          int a, y, m;
          int wday;
    
          a = (14 - month) / 12;
          y = year + 4800 - a;
          m = month + 12 * a - 3;
          wday = day + (153*m+2)/5 + 365*y + y/4 - y/100 + y/400 + 2;
          wday = wday % 7;
          return wday;
      }
    

Source:
[https://github.com/ruby/ruby/blob/5396d8a1ab52b4da4f51991094...](https://github.com/ruby/ruby/blob/5396d8a1ab52b4da4f5199109472fe7f8ea43085/time.c#L1260)

~~~
cuoverhere
perl!

    
    
      sub GetDayofWeek {
    
        my ($year, $month, $day) = @_;
        
         my @monthTable = (0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4);
         
         my @DayofWeek = qw(Sunday Monday Tuesday Wednesday Thursday Friday Saturday Sunday);
         
         $year -=  ($month < 3) ? 1: 0;
         
         return $DayofWeek[($year + $year / 4 - $year / 100 + $year / 400 + $monthTable[$month - 1] + $day) % 7];
           
      }

------
jhallenworld
A function you sometimes need is to convert date to business week of year
(output is year, week number) where "week 1 is the week with the year's first
Thursday in it (the formal ISO definition)".

[https://en.wikipedia.org/wiki/ISO_8601#Week_dates](https://en.wikipedia.org/wiki/ISO_8601#Week_dates)

Week numbers are useful for comparing equal length business quarters. Each
quarter has 13 weeks except the last which can have 14 (but not much business
last week of year).

~~~
mark-r
That's on the site too: [https://www.programmingalgorithms.com/algorithm/week-
of-year](https://www.programmingalgorithms.com/algorithm/week-of-year)

Seems a bit over complicated though, I wonder if it could be simplified the
way the day-of-week calculation is simplified.

------
mark-r
I really like the trick of subtracting one from the year for January and
February, it makes leap days come at the end of the year. This simplifies the
calculation greatly.

------
sxv
This fails for dates prior to adoption of the Gregorian calendar (~1582).

~~~
stygiansonic
To make things even more confusing, it depends on the particular location, as
different regions adopted the Gregorian calendar at different points in time.

------
coreyp_1
If it doesn't use left-pad, I don't believe it.

------
deadowl
It's a fun problem to think about, but I'm just going to use the date library
because it's really easy to screw up.

------
plugnburn
In JS we can rely on the Date.getDay prototype. Here's the ES6 flavour:

    
    
      weekDay = (dateObj) => ['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday'][dateObj.getDay()]

