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]
This commit is contained in:
Jeremy Evans 2019-06-21 10:33:06 -07:00
Родитель 8f1062127e
Коммит a9d4f2d03c
2 изменённых файлов: 23 добавлений и 1 удалений

Просмотреть файл

@ -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

Просмотреть файл

@ -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