From aadc36f736c322d584ed350deb3e9323c38cd649 Mon Sep 17 00:00:00 2001 From: Josh Cronemeyer Date: Sat, 12 Aug 2023 11:38:21 -0700 Subject: [PATCH] fix week based dates --- lib/timecop/time_extensions.rb | 23 +++++++++++++++-------- test/date_strptime_scenarios.rb | 13 ++++++++----- 2 files changed, 23 insertions(+), 13 deletions(-) diff --git a/lib/timecop/time_extensions.rb b/lib/timecop/time_extensions.rb index f261563..3250c45 100644 --- a/lib/timecop/time_extensions.rb +++ b/lib/timecop/time_extensions.rb @@ -58,14 +58,21 @@ def strptime_with_mock_date(str = '-4712-01-01', fmt = '%F', start = Date::ITALY Date.new(year, mon, d[:mday], start) elsif d[:yday] Date.new(year, 1, 1, start).next_day(d[:yday] - 1) - elsif d[:cwyear] || d[:cweek] || d[:wnum1] || d[:wday] || d[:cwday] - day_of_week_from_monday = if d[:wday] - (d[:wday] + 6)%7 + 1 - else - d[:cwday] || 1 - end - week = d[:cweek] || d[:wnum1] || now.strftime('%W').to_i - Date.commercial(year, week, day_of_week_from_monday, start) + elsif d[:cwyear] || d[:cweek] || d[:wnum0] || d[:wnum1] || d[:wday] || d[:cwday] + week = d[:cweek] || d[:wnum1] || d[:wnum0] || now.strftime('%W').to_i + if d[:wnum0] #Week of year where week starts on sunday + if d[:cwday] #monday based day of week + Date.strptime_without_mock_date("#{year} #{week} #{d[:cwday]}", '%Y %U %u', start) + else + Date.strptime_without_mock_date("#{year} #{week} #{d[:wday] || 0}", '%Y %U %w', start) + end + else #Week of year where week starts on monday + if d[:wday] #sunday based day of week + Date.strptime_without_mock_date("#{year} #{week} #{d[:wday]}", '%Y %W %w', start) + else + Date.strptime_without_mock_date("#{year} #{week} #{d[:cwday] || 1}", '%Y %W %u', start) + end + end elsif d[:seconds] Time.at(d[:seconds]).to_date else diff --git a/test/date_strptime_scenarios.rb b/test/date_strptime_scenarios.rb index b7bd19e..de3d619 100644 --- a/test/date_strptime_scenarios.rb +++ b/test/date_strptime_scenarios.rb @@ -51,6 +51,10 @@ def test_date_strptime_with_commercial_week_date_and_day_of_week_from_sunday assert_equal Date.strptime('1984-09-7', '%G-%V-%u'), Date.new(1984, 3, 04) end + def test_date_strptime_week_number_of_year_day_of_week_sunday_start + assert_equal Date.strptime('1984 09 0', '%Y %U %w'), Date.new(1984, 2, 26) + end + def test_date_strptime_with_iso_8601_week_date assert_equal Date.strptime('1984-W09-1', '%G-W%V-%u'), Date.new(1984, 2, 27) end @@ -124,11 +128,10 @@ def test_strptime_converts_back_and_forth_between_date_and_string_for_many_forma '%Y %W %u', '%C %y %W %w', '%C %y %W %u', - #TODO Support these formats - # '%Y %U %w', - # '%Y %U %u', - # '%C %y %U %w', - # '%C %y %U %u', + '%Y %U %w', + '%Y %U %u', + '%C %y %U %w', + '%C %y %U %u', ].each do |fmt| s = d.strftime(fmt) d2 = Date.strptime(s, fmt)