52 comments

[ 3.4 ms ] story [ 122 ms ] thread
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...

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.

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/dayofw...
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)
Leap seconds don't occur systematically, so there's no algorithm that can always determine the correct day of the week by the number of seconds or ticks from epoch. The algorithm of the subject line abstracts over leap seconds by referencing a calendar rather than a clock...i.e. a calendar being a document that names future times rather than an instrument that reports the current time.
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).
So all the hard work of converting year/month/day to InternalTicks is done at creation time, greatly simplifying the weekday calculation occurring later.
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];
Wonder why you were downvoted
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

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).

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...
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];
       
  }
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.
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?

Because that's how 99% of calendars in the US order the days. It's not a choice, it's convention.
I've seen calendars use this format, but why? To me it would seem not to line up with how we treat our weeks? We talk about the work week as a contiguous block, and the weekend the same way, so why split one of those blocks over two rows?
If it were any other format other than what you were accustomed to, you'd still be asking the same question. It's just a common convention, it doesn't need to have any deeper meaning.
I think Daneel_'s point still holds true. Even though the convention in the US is that weeks start on Sunday, in natural language you can hear that people's mental model differ. For example

- "weekend" (that's "week end") includes both Saturday and Sunday

- "beginning of next week" means Monday/Tuesday

- "next week" in general seems to start on the Monday

So to me, the convention in the US seems to be more about how calendars are displayed than how we think about the week. Our two models disagree, so it's reasonable to ask why.

You can sleep in on Sunday, but you need to go to sleep at a reasonable hour which IMO suggests your preparing for the week aka starting it.

On the other hand Friday night through Saturday night is party time.

It's what you use in the US which you seem to think is some kind of standard. The rest of the world follows ISO 8601 where Monday is the first day.
It's what you use in the US which you seem to think is some kind of standard.

No, the commenter seems to think it's some kind of convention, as he clearly stated. The original question was, "but why do some people think the week starts on a Sunday?", and the answer given explains why "some people" (i. e., those in the U. S.) might think of Sunday as the first day of the week. Move along, no U.S.-centric conspiracies to be found here.

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.

Great explanation, thank you.
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

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

Monday to Sunday: https://www.gov.uk/guidance/statutory-sick-pay-manually-calc...

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,...

> 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...

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

The week in the liturgical calendar starts on Sunday. I don't know when did the civil calendar diverge, but you can see sometimes traces of the old usage in the names of the days of the week (segunda-feira, etc. in Portuguese, Mittwoch in German).
I used to consider Monday as the first day of the week. I started the week fed-up and ended it tired.

I chose to change the way I think and switched my calendars to start on Sunday. This allowed me to change my state of mind and start the week with activities that I enjoy and spare time.

It is 100% in my head, but it worked for me.

The problem which required your trick was also 100% in your head! We are such fascinating creatures.
It actually starts on Sunday in some countries, still using primitive calendars...
Seems relevant, Cron supports using 0 or 7 to refer to Sunday.
What a fascinating way to solve the problem.

You want Sunday as the first day? Fine, do your index zero-based and Sunday is Zero.

You want Monday as the first day? Fine, index 1-based and use 7 for Sunday.

Kind of brilliant.

Completely agree. When I first started using cron I was chuffed at this.
The U.S. convention to start the week on a Sunday dates to Christian conventions which date to Jewish conventions. In the Latin-speaking Christian world (and also later among the Quakers), Sunday was considered the "first day", Monday the "second day", etc., because that's what the Genesis creation narrative says.

https://en.wikipedia.org/wiki/Names_of_the_days_of_the_week#...

This is taken from the Jewish understanding in Genesis 1:3 to 2:3. According to this tradition, the world was created on a Sunday, and that's why it's the first day (יום ראשון 'first day').

https://en.wikipedia.org/wiki/Genesis_creation_narrative#Six...

Early Christianity mostly adopted Sunday as the "Lord's Day". (You can still see the history of the two Western weekend days in Latin and Romance languages; for example in Portuguese Saturday is sábado 'sabbath' < L. sabbatum, while Sunday is domingo 'Lord's day' < L. dominicus.)

https://en.wikipedia.org/wiki/Sunday#Christian_usage

https://en.wikipedia.org/wiki/Lord's_Day

Actually it says "day one" (יום אחד).
Oh yeah, יום ראשון is the name of the weekday, not what it's called in Genesis 1:5. Thanks for the correction.
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
I'm pretty sure the post's solution is wrong.

Examples:

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

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

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.
This fails for dates prior to adoption of the Gregorian calendar (~1582).
To make things even more confusing, it depends on the particular location, as different regions adopted the Gregorian calendar at different points in time.
If it doesn't use left-pad, I don't believe it.
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 :)

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()]