Reputation: 1047
Date.commercial
method to find start of week (Monday) is not working for 53rd week
Date.commercial(2018, 1, 1)
#=> 2018-01-01
Date.commercial(2018, 52, 1)
#=> 2018-12-24
It throws error when I try to find Monday of 53rd week in years which has 53 weeks.
Date.commercial(2018, 53, 1)
# ArgumentError: invalid date
Also, its definition is also not clear to me. Like how these two are behaving so differently:
Date.commercial(2015, 1, 1)
#=> 2014-12-29
Date.commercial(2016, 1, 1)
#=> 2016-01-04
I think its because definition of Date.commercial()
to convert week number to date is different from that of Date.strftime("%W")
. Is there any method which can convert year's week number to Monday date of the week consistent with Date.strftime("%W")
, i.e. reverse function of Date.strftime("%W")
?
Upvotes: 1
Views: 999
Reputation: 114218
Is there any method which can convert year's week number to Monday date of the week consistent with
Date.strftime("%W")
, i.e. reverse function ofDate.strftime("%W")
?
You could use strptime
:
Date.strptime('2018-W53', '%Y-W%W')
#=> #<Date: 2018-12-31 ((2458484j,0s,0n),+0s,2299161j)>
Note that %W
and %V
(commercial week) are defined differently and produce different results.
%W
is defined as:
The week 1 of YYYY starts with a Monday. The days in the year before the first week are in week 0.
%V
is defined as:
The week 1 of YYYY starts with a Monday and includes YYYY-01-04. The days in the year before the first week are in the last week of the previous year.
Some examples:
Date.new(2018, 1, 1).strftime('%Y-W%W / %G-CW%V') #=> "2018-W01 / 2018-CW01"
Date.new(2018, 12, 31).strftime('%Y-W%W / %G-CW%V') #=> "2018-W53 / 2019-CW01"
Date.new(2019, 1, 1).strftime('%Y-W%W / %G-CW%V') #=> "2019-W00 / 2019-CW01"
Date.new(2019, 12, 31).strftime('%Y-W%W / %G-CW%V') #=> "2019-W52 / 2020-CW01"
Date.new(2020, 1, 1).strftime('%Y-W%W / %G-CW%V') #=> "2020-W00 / 2020-CW01"
Date.new(2020, 12, 31).strftime('%Y-W%W / %G-CW%V') #=> "2020-W52 / 2020-CW53"
Date.new(2021, 1, 1).strftime('%Y-W%W / %G-CW%V') #=> "2021-W00 / 2020-CW53"
Date.new(2021, 12, 31).strftime('%Y-W%W / %G-CW%V') #=> "2021-W52 / 2021-CW52"
Upvotes: 5
Reputation: 198436
From API docs:
the first calendar week of the year is the one that includes the first Thursday of that year. In the Gregorian calendar, this is equivalent to the week which includes January 4.
Thus, 2018 doesn't have 53 weeks. The last day of the last week of 2018 is:
Date.commercial(2018, 52, 7)
# => #<Date: 2018-12-30 ((2458483j,0s,0n),+0s,2299161j)>
followed by the first week of 2019:
Date.commercial(2019, 1, 1)
# => #<Date: 2018-12-31 ((2458484j,0s,0n),+0s,2299161j)>
You seem to be working under the premise that 2018-12-31 is in 2018. It is not, not in Commercial date. If you're going to use the commercial year instead of the calendar year, use %G
, not %Y
, to get the commercial year, and %V
for the week instead of %W
.
date2018_12_31 = Date.commercial(2019, 1, 1)
date2018_12_31.strftime("%Y %W") # WRONG
# => "2018 53"
date2018_12_31.strftime("%G %V") # CORRECT
# => "2019 01"
Upvotes: 4