Skip to main content
Add explanation
Source Link
fireflame241
  • 16.3k
  • 2
  • 29
  • 72

JavaScript (Node.js), 166 bytes

d=>{w=(d-978336e6)/r+.5&7
for(D=0,e=new Date(d.getTime()+(7-w)*r);e.getMonth()!=0||e.getDate()!=4;D++)e.setTime(e.getTime()-r)
return[e.getYear(),8+D>>3,w+1]}
r=864e5

Takes input as a Javascript date object. Outputs as a 3-element list [week-year, week number, weekday number]. The week-numbering year is expressed as a 2-digit year (year minus 1900). If this is not acceptable, change e.getYear() to e.getFullYear() for +4 bytes.

Try it online!

Huh?

r=864e5 // milliseconds in a day
d=>{ // Take d as a date object
 w= // w is 1 less than the week number
  (d-978336e6) // milliseconds since Jan 1, 2001
  /r+  // Divide to get days
  .5&7 // Round (up or down) to nearest integer, and take mod 8.
       // This rounding smooths over DST and related variations
       // Variations over 12 hours do not occur, as far as I know
 for(
  D=0,  // D will be the number of days since the last Jan 4
  e=new Date(d.getTime()+(7-w)*r); // Initialize e to be the end of this week
  e.getMonth()!=0||e.getDate()!=4; // While e is not Jan 4 of any year:
   D++  // Increment D
  ) e.setTime(e.getTime()-r)  // Set e to the day before
 return [
  e.getYear(), // The week-numbering year of d is the same as the Gregorian year of the preceding Jan 4
  8+D>>3, // Convert days elapsed into weeks since Jan 4
  w+1 // the week number
 ]
}

JavaScript (Node.js), 166 bytes

d=>{w=(d-978336e6)/r+.5&7
for(D=0,e=new Date(d.getTime()+(7-w)*r);e.getMonth()!=0||e.getDate()!=4;D++)e.setTime(e.getTime()-r)
return[e.getYear(),8+D>>3,w+1]}
r=864e5

Takes input as a Javascript date object. Outputs as a 3-element list [week-year, week number, weekday number]. The week-numbering year is expressed as a 2-digit year (year minus 1900). If this is not acceptable, change e.getYear() to e.getFullYear() for +4 bytes.

Try it online!

JavaScript (Node.js), 166 bytes

d=>{w=(d-978336e6)/r+.5&7
for(D=0,e=new Date(d.getTime()+(7-w)*r);e.getMonth()!=0||e.getDate()!=4;D++)e.setTime(e.getTime()-r)
return[e.getYear(),8+D>>3,w+1]}
r=864e5

Takes input as a Javascript date object. Outputs as a 3-element list [week-year, week number, weekday number]. The week-numbering year is expressed as a 2-digit year (year minus 1900). If this is not acceptable, change e.getYear() to e.getFullYear() for +4 bytes.

Try it online!

Huh?

r=864e5 // milliseconds in a day
d=>{ // Take d as a date object
 w= // w is 1 less than the week number
  (d-978336e6) // milliseconds since Jan 1, 2001
  /r+  // Divide to get days
  .5&7 // Round (up or down) to nearest integer, and take mod 8.
       // This rounding smooths over DST and related variations
       // Variations over 12 hours do not occur, as far as I know
 for(
  D=0,  // D will be the number of days since the last Jan 4
  e=new Date(d.getTime()+(7-w)*r); // Initialize e to be the end of this week
  e.getMonth()!=0||e.getDate()!=4; // While e is not Jan 4 of any year:
   D++  // Increment D
  ) e.setTime(e.getTime()-r)  // Set e to the day before
 return [
  e.getYear(), // The week-numbering year of d is the same as the Gregorian year of the preceding Jan 4
  8+D>>3, // Convert days elapsed into weeks since Jan 4
  w+1 // the week number
 ]
}
Source Link
fireflame241
  • 16.3k
  • 2
  • 29
  • 72

JavaScript (Node.js), 166 bytes

d=>{w=(d-978336e6)/r+.5&7
for(D=0,e=new Date(d.getTime()+(7-w)*r);e.getMonth()!=0||e.getDate()!=4;D++)e.setTime(e.getTime()-r)
return[e.getYear(),8+D>>3,w+1]}
r=864e5

Takes input as a Javascript date object. Outputs as a 3-element list [week-year, week number, weekday number]. The week-numbering year is expressed as a 2-digit year (year minus 1900). If this is not acceptable, change e.getYear() to e.getFullYear() for +4 bytes.

Try it online!