Add ActiveSupport::TimeZone#abbr

As of Ruby 2.6, ::Time supports rich timezone objects and expects them
to follow a similar API to tzinfo. Mostly we already do this with
ActiveSupport::TimeZone, delegating to the underlying tzinfo object,
except we were missing the API to display the timezone's name.

Calling strftime with "%Z" will try the following on the timezone:
* zone.abbr(time)
* zone.strftime("%Z", time)
* zone.name

Because we only implemented name, a ::Time created with an
ActiveSupport::TimeZone would "abbreviate" awkwardly to the full tz
identifier (like "12:34:00 America/Vancouver" instead of "12:34:00
PDT"). This commit implements abbr to make these Times format the same
way as TimeWithZone.

Co-authored-by: Jason Kim <jasonkim@github.com>
This commit is contained in:
John Hawthorn 2024-06-04 17:38:04 -07:00
parent 8159498aea
commit 262713413c
2 changed files with 16 additions and 0 deletions

@ -568,6 +568,12 @@ def periods_for_local(time) # :nodoc:
tzinfo.periods_for_local(time)
end
# Available so that TimeZone instances respond like +TZInfo::Timezone+
# instances.
def abbr(time)
tzinfo.abbr(time)
end
def init_with(coder) # :nodoc:
initialize(coder["name"])
end

@ -876,4 +876,14 @@ def test_yaml_load
loaded = YAML.respond_to?(:unsafe_load) ? YAML.unsafe_load(payload) : YAML.load(payload)
assert_equal(ActiveSupport::TimeZone["Pacific/Honolulu"], loaded)
end
def test_abbr
zone = ActiveSupport::TimeZone["America/Toronto"]
assert_equal "EST", zone.abbr(Time.utc(2000, 4, 2, 6))
assert_equal "EDT", zone.abbr(Time.utc(2000, 4, 2, 7))
assert_equal "EDT", zone.abbr(Time.utc(2000, 4, 2, 8))
assert_equal "EDT", zone.abbr(Time.utc(2000, 10, 29, 5))
assert_equal "EST", zone.abbr(Time.utc(2000, 10, 29, 6))
assert_equal "EST", zone.abbr(Time.utc(2000, 10, 29, 7))
end
end