aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeremy Evans <code@jeremyevans.net>2019-06-21 10:33:06 -0700
committerJeremy Evans <code@jeremyevans.net>2019-11-21 03:32:20 +0200
commita9d4f2d03c847ec1c89dc03a5076a9fa29ffa61f (patch)
tree85fc32549b43796e4f4388383ea5907f6c976022
parent8f1062127e40767240aa0a0fe18fd48687bc04e9 (diff)
downloadruby-a9d4f2d03c847ec1c89dc03a5076a9fa29ffa61f.tar.gz
Support %U/%u/%W/%w/%V/%g/%G formats in Time.strptime
Most of these formats were documented as supported, but were not actually supported. Document that %g and %G are supported. If %U/%W is specified without yday and mon/mday are not specified, then Date.strptime is used to get the appropriate yday. If cwyear is specifier without the year, or cwday and cweek are specified without mday and mon, then use Date.strptime and convert the resulting value to Time, since Time.make_time cannot handle those conversions Fixes [Bug #9836] Fixes [Bug #14241]
-rw-r--r--lib/time.rb13
-rw-r--r--test/test_time.rb11
2 files changed, 23 insertions, 1 deletions
diff --git a/lib/time.rb b/lib/time.rb
index b1d75539aa..f27bacde65 100644
--- a/lib/time.rb
+++ b/lib/time.rb
@@ -397,6 +397,9 @@ class Time
# %D :: Date (%m/%d/%y)
# %e :: Day of the month, blank-padded ( 1..31)
# %F :: Equivalent to %Y-%m-%d (the ISO 8601 date format)
+ # %g :: The last two digits of the commercial year
+ # %G :: The week-based year according to ISO-8601 (week 1 starts on Monday
+ # and includes January 4)
# %h :: Equivalent to %b
# %H :: Hour of the day, 24-hour clock (00..23)
# %I :: Hour of the day, 12-hour clock (01..12)
@@ -456,7 +459,15 @@ class Time
else
year = d[:year]
year = yield(year) if year && block_given?
- t = make_time(date, year, d[:yday], d[:mon], d[:mday], d[:hour], d[:min], d[:sec], d[:sec_fraction], d[:zone], now)
+ yday = d[:yday]
+ if (d[:cwyear] && !year) || ((d[:cwday] || d[:cweek]) && !(d[:mon] && d[:mday]))
+ # make_time doesn't deal with cwyear/cwday/cweek
+ return Date.strptime(date, format).to_time
+ end
+ if (d[:wnum0] || d[:wnum1]) && !yday && !(d[:mon] && d[:mday])
+ yday = Date.strptime(date, format).yday
+ end
+ t = make_time(date, year, yday, d[:mon], d[:mday], d[:hour], d[:min], d[:sec], d[:sec_fraction], d[:zone], now)
end
t
end
diff --git a/test/test_time.rb b/test/test_time.rb
index e4fea31945..ca20788aac 100644
--- a/test/test_time.rb
+++ b/test/test_time.rb
@@ -528,6 +528,17 @@ class TestTimeExtension < Test::Unit::TestCase # :nodoc:
assert_equal(15, t.hour)
end
+ def test_strptime_wuvg
+ assert_equal(Time.local(2019, 1, 30), Time.strptime("3 4 2019", "%w %W %Y"))
+ assert_equal(Time.local(2019, 2, 7), Time.strptime("4 5 2019", "%u %U %Y"))
+ assert_equal(Time.local(2019, 1, 28), Time.strptime("4 2019", "%W %Y"))
+ assert_equal(Time.local(2019, 2, 3), Time.strptime("5 2019", "%U %Y"))
+ assert_equal(Time.local(2019, 1, 1), Time.strptime("1 2 2019", "%V %w %G"))
+ assert_equal(Time.local(2016, 1, 1), Time.strptime("53 5 15", "%V %w %g"))
+ assert_equal(Time.local(2018, 12, 31), Time.strptime("1 2019", "%V %G"))
+ assert_equal(Time.local(2015, 12, 28), Time.strptime("53 15", "%V %g"))
+ end
+
def test_nsec
assert_equal(123456789, Time.parse("2000-01-01T00:00:00.123456789+00:00").tv_nsec)
end