Skip to content

Instantly share code, notes, and snippets.

@havenwood
Last active January 25, 2020 00:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save havenwood/32675cfb7af06c112b9f746102505b32 to your computer and use it in GitHub Desktop.
Save havenwood/32675cfb7af06c112b9f746102505b32 to your computer and use it in GitHub Desktop.
A refinement to fix the Time::strptime lack of %U/%u/%W/%w/%V/%g/%G support pre-2.7 — see https://github.com/ruby/ruby/commit/a9d4f2d03c847ec1c89dc03a5076a9fa29ffa61f#diff-0ead6351265632d68f106a2b1a98f5f9
require 'time'
module FixStrptime
refine Time.singleton_class do
def strptime(date, format, now=self.now)
d = Date._strptime(date, format)
raise ArgumentError, "invalid date or strptime format - `#{date}' `#{format}'" unless d
if seconds = d[:seconds]
if sec_fraction = d[:sec_fraction]
usec = sec_fraction * 1000000
usec *= -1 if seconds < 0
else
usec = 0
end
t = Time.at(seconds, usec)
if zone = d[:zone]
force_zone!(t, zone)
end
else
year = d[:year]
year = yield(year) if year && block_given?
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
end
end
using FixStrptime
p Time.strptime('202001', '%Y%U')
#>> 2020-01-05 00:00:00 -0800
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment