无法使用 Date.commercial 方法找到第 53 周的开始

Ume*_*tra 2 ruby ruby-on-rails week-number ruby-on-rails-5

Date.commercial 找到一周开始(星期一)的方法在第 53 周不起作用

Date.commercial(2018, 1, 1)
#=> 2018-01-01
Date.commercial(2018, 52, 1)
#=> 2018-12-24
Run Code Online (Sandbox Code Playgroud)

当我尝试在有 53 周的年份中查找第 53 周的星期一时,它会引发错误。

Date.commercial(2018, 53, 1)
# ArgumentError: invalid date
Run Code Online (Sandbox Code Playgroud)

此外,它的定义对我来说也不清楚。就像这两个人的行为如此不同:

Date.commercial(2015, 1, 1)
#=> 2014-12-29

Date.commercial(2016, 1, 1)
#=> 2016-01-04
Run Code Online (Sandbox Code Playgroud)

我认为这是因为Date.commercial()将周数转换为日期的定义与Date.strftime("%W"). 是否有任何方法可以将年份的周数转换为与 一致的星期几Date.strftime("%W"),即 的反向函数Date.strftime("%W")

Ama*_*dan 5

来自 API 文档:

一年中的第一个日历周是包括该年第一个星期四的那个日历周。在公历中,这相当于包括 1 月 4 日在内的一周。

因此,2018 年没有53 周。2018年最后一周的最后一天是:

Date.commercial(2018, 52, 7)
# => #<Date: 2018-12-30 ((2458483j,0s,0n),+0s,2299161j)> 
Run Code Online (Sandbox Code Playgroud)

接下来是 2019 年的第一周:

Date.commercial(2019, 1, 1)
# => #<Date: 2018-12-31 ((2458484j,0s,0n),+0s,2299161j)> 
Run Code Online (Sandbox Code Playgroud)

你好像是在 2018-12-31 是 2018 年的前提下工作的。它不是,不在商业日期。如果您要使用商业年而不是日历年,请使用%G, not%Y来获取商业年,并%V使用周而不是%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"
Run Code Online (Sandbox Code Playgroud)


Ste*_*fan 5

有没有什么方法可以将一年的周数转换为与 一致的一周的星期一日期Date.strftime("%W"),即 的逆函数Date.strftime("%W")

你可以使用strptime

Date.strptime('2018-W53', '%Y-W%W')
#=> #<Date: 2018-12-31 ((2458484j,0s,0n),+0s,2299161j)>
Run Code Online (Sandbox Code Playgroud)

请注意,%W%V(商业周)的定义不同并产生不同的结果。

%W定义为:

YYYY 的第一周从星期一开始。一年中第一周之前的天数位于第 0 周。

%V定义为:

YYYY 的第一周从星期一开始,包括 YYYY-01-04。一年中第一周之前的天数是上一年的最后一周。

一些例子:

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"
Run Code Online (Sandbox Code Playgroud)