g | x | w | all
Bytes Lang Time Link
435ARM64 AArch64241212T175301Zfgeorgat
098python2241211T204759Zfgeorgat
3101Python3 for a fistful of bytes 101241210T182658Zfgeorgat
126C220129T203457Zbmann
110Perl170517T092846ZLayosh
109Python 2151128T100323ZSherlock
125PHP 101 97 103110617T122728Zrintaun
123Javascript110617T082105ZDocMax
129C110617T090602ZJoey Ada
092Ruby110617T082135ZHoward

ARM64 (AArch64), 435 without comments

For comedic effect, fun & profit, here is an arm64 assembly language implementation.

This relies on the kefalonian constant 0xD4E7D404 / 3574503828 and it can be also implemented in 32bit assembly, modulo the dear command sdiv.

Parameters: y in x0, m in x1, d in x2

Result: in x0

    .text
    .global dow

dow:
    cmp     x1, #3
    b.ge    no_decr
    sub     x0, x0, #1

no_decr:

    // y//4
    mov     x9, x0
    sdiv    x10, x9, #4

    // y//100
    sdiv    x11, x0, #100

    // y//400
    sdiv    x12, x0, #400

    // shift_amount = 36 - 3*m
    mul     x13, x1, #3
    mov     x14, #36
    sub     x14, x14, x13

    // month_val = (3574503828 >> shift_amount) & 7
    mov     x15, 0xD4E7D404  // 3574503828
    lsr     x15, x15, x14
    and     x15, x15, #7

    // val = y + y//4 - y//100 + y//400 + month_val + d
    add     x0, x0, x10
    sub     x0, x0, x11
    add     x0, x0, x12
    add     x0, x0, x15
    add     x0, x0, x2

    // result = val % 7
    // Use sdiv: remainder = val - (val/7)*7
    sdiv    x1, x0, #7
    msub    x0, x1, #7, x0

    ret

Original algorithm:

## This algorithm shows the day of the week for a given yyyy/mm/dd calendar day, where 0=Sunday, 1=Monday etc. 
>>> def dow(y, m, d): 
      y -= m < 3 
      return (y + y//4 - y//100 + y//400 + (3574503828>>(36-3*m)) % 8 + d) % 7 
>>> dow(1,1,1) 
1 
>>> dow(1983,7,28) 
4 
>>> dow(1975,5,25) 
0 
>>> dow(2018,9,13) 
4 

Reference from quora: https://qr.ae/psZnDr

python2 -- 98 bytes

This improves upon the existing python3 answer:

def f(s):y,m,d=map(int,[s[:4],s[4:6],s[6:]]);y-=m<3;return(y+y/4-y/100+y/400+(3246*m^130159)+d)%7

There is not much to say other than that this is also 0-based for Sunday.

Python3: for a fistful of bytes -- 101

In case anyone comes along craving for a crystal clear python incarnation of the sakamoto algorithm, this entry just became a winner in the year 2024 International Obfuscated Python Code Contest.

So, this first one is in Python3 however this version will not trade clarity for size. Or, not really ;-)

def DayOfWeek( y, m, d, tuple=' (["upseal.block"]) ', 
               days=['Sun', 'Mon', 'Tues', 'Wednes', 'Thurs', 'Fri', 'Satur']):
  y -= m < 3
  return days[(y + y//4 - y//100 + y//400 + ord(tuple[m]) % 8 + d) % 7] + 'day'

And this is the sub-optimal readable variant which would make it compliant to OP's call:

def DayOfWeek( s, tuple=' (["upseal.block"]) ' ):
  m=int(s[4:6]);y,d=int(s[:4])-(m<3),int(s[6:])
  return (y + y//4 - y//100 + y//400 + ord(tuple[m]) % 8 + d) % 7

And finally, here is the very brief version variation:

def f(s):y,m,d=map(int,[s[:4],s[4:6],s[6:]]);y-=m<3;return(y+y//4-y//100+y//400+(3246*m^130159)+d)%7

It should work correctly for any day of the Gregorian calendar and, well, it is Y2K safe, too.

C (126 bytes)

main(y,m,d){scanf("%4d%2d%2d",&y,&m,&d);y%=400;putchar(((5*y+3)/4-y/100+"-KGGJLHJFIKGI"[m]+(!(y%4)&&m>2&&y%100||!y)+d)%7+48);}

Try it online!

Perl -- 110 bytes

Here is a solution to be run with perl -p source.pl OR perl -pe 'here-is-code'.

s/((..)(..))(..)(..)/(1+3*$1+$2-2*($1%4+$2%4)-(2<$4?$4+(1&$4&&4-(8&$4)):(2^$4)+(!($3%4)-!-$3+!($2%4)))+$5)%7/e

Simply copy-paste the test cases to stdin.

This seems to be the only code without variables, string constants and divisions.

Python 2, 83 116 113 109 bytes

Implements Sakamoto's algorithm. Golfing suggestions welcome. Try it online!

Edit: I should have fixed this ages ago. -6 bytes from Jonathan Allan's suggestions +2 bytes to actually fixing the code.

def w(s):m=int(s[4:6]);y,d=int(s[:4])-(m<3),int(s[6:]);return(y+y/4-y/100+y/400+int('032503514624'[m-1])+d)%7

PHP - 101 97 103 125 characters

Code

<?php fscanf(STDIN,"%4d%2d%2d",$y,$m,$d);@$a=a032503514624;$y-=$m<3;$z=$y+1;echo($y+$y/4%$z-$y/100%$z+$y/400%$z+$a[$m]+$d)%7;

Note

Unfortunately, due to PHP's dynamic, weak typing, the Sakamoto algorithm doesn't function properly without explicitly flooring each division operation.

Javascript, 126 123 characters

Using Sakamoto's algorithm with 0 = Sunday:

prompt().replace(/(....)(..)(..)/,function(_,y,m,d){y-=m<3;alert((+d+y-~(y/4)+~(y/100)-~(y/400)+ +".621462403513"[+m])%7)})

I suspect the divisions can be collapsed, but right now I'm not seeing it.

Edit: Improved the divisions (no need to ~~ when you can just ~).

C - 129

main(y,m,d,s)
{
    scanf("%04d%02d%02d",&y,&m,&d);
    y-=s=86400;
    d+=y+"-addgbegcfadf"[m];
    m>2?y++:0;
    putchar(48+(d+y/4-y/100+y/400+s+s)%7);
}

This abuses how division rounds toward zero, at least on my system (Linux x86).

The magic constant, 86400, serves two purposes:

It also happens to be the number of seconds in a day.

Ruby, 95 92 characters

Plain straightforward ruby implementation with 0:Monday, ...

p ((y=(d=gets.to_i)/(k=100)/k-((m=d/k%k)<3?1:0))+y/4-y/k+y/400+"squsptrotqro"[-m].ord+d%k)%7