What week is it?

MATL, 50 bytes

Thanks to @Neil and @NickClifford for pointing out a mistake, now corrected

ZO1)TThXJYOXIGYO&:8XO!s310=sJ4B-YOIq&:8XO!s310=sX\

Try it online! Or verify all test cases.

Explanation

This uses the three date/time conversion functions that there are in MATL:

  • XO: convert date and time to string format;
  • YO: convert date and time to serial date number;
  • ZO: convert date and time to vector of components.

Determining if week "0" should become 52 or 53 was costly, because MATL cannot define callable functions to reuse the 8XO!s310=s part. Reusing by means of loop with a branch only saves one byte, and complicates the explanation, so probably not worth it.

Also, something could be gained inputting the date as a [year, month, day] array; but the I would not use all three date functions :-)

Consider input '17MAY2017' as an example.

       % Implicit input
       % STACK: '17MAY2017'
ZO     % Convert to date vector
       % STACK: [2017 5 17]
1)     % Get first entry: year
       % STACK: 2017
TTh    % Append [1 1]
       % STACK: [2017 1 1]
XJ     % Copy to clipboard J
YO     % Convert to date number
       % STACK: 736696
XI     % Copy to clipboard I
GYO    % Push input again. Convert to date number
       % STACK: [736696 736832]
&:     % Binary range
       % STACK: [736696 736697 736698 ... 736832]
8XO    % Convert to date string with format 'ddd': day of week
       % STACK: ['Sun'; 'Mon'; 'Tue'; ... ; 'Wed']
!s     % Sum of each row (chars are interpreted as code points)
       % STACK: [310 298 302 ...  288]
310=   % Compare with 310 (sum of 'Sun')
       % STACK: [1 0 0 ... 0]
s      % Sum of array. If is 0, it needs to be transformed into 52 or 53,
       % depending on the number of Sundays the previous year contains.
       % STACK: 20
J      % Paste from clipboard J
       % STACK: 20, [2017 1 1]
4B-    % Push [1 0 0] and subtract element-wise
       % STACK: 20, [2016 1 1]
YO     % COnvert to date number
       % STACK: 20, 736330
I      % Paste from clipboard I
       % STACK: 20, 736330, 736696
q      % Subtract 1
       % STACK: 20, 736330, 736695
&:     % Binary range
       % STACK: 20, [736330 736331 736332 ... 736695]
8XO    % Convert to date string with format 'ddd': day of week
       % STACK: 20, ['Fri'; 'Sat'; 'Sun'; ... ; 'Sat']
!s     % Sum of each row (chars are interpreted as code points)
       % STACK: 20, [289 296 310 ... 296]
310=   % Compare with 310 (sum of 'Sun')
       % STACK: 20, [0 0 1 ... 0]
s      % Sum of array
       % STACK: 20, 52
X\     % 1-based modulo
       % STACK: 20
       % Implicit display

JavaScript (ES6), 82 80 bytes

Takes input as (year,month,day).

let f =

(y,m,d)=>-~((((x=new Date(y,m-1,d))-new Date(y,0,1))/864e5+372-x.getDay())/7%53)

console.log(f(2017, 5,17)) // 20
console.log(f(2013, 1, 3)) // 53
console.log(f(2017, 1, 1)) // 1
console.log(f(1901, 5,17)) // 19
console.log(f(2100,12,31)) // 52
console.log(f(2015, 7, 7)) // 27


JavaScript (Firefox 34+), 70 bytes

with(new Date())y.value=getFullYear(),m.value=getMonth()+1,d.value=getDate()+1
f=
(y,m,d)=>new Date(y,--m,d-new Date(y,m,d).getDay()).toLocaleFormat`%U`
<div oninput=w.value=f(y.value,m.value,d.value)><input id=y type=number><input id=m type=number min=1 max=12><input id=d type=number min=1 max=31><input id=w readonly placeholder=Output>

Works by finding the first day of the week containing the given date, then finding that day's week number (which is never zero).

Tags:

Date

Code Golf