Getting a Time Zone abbreviation from the full name?

There’s got to be an easier way…

I am building an event manager and as part of it, the user selects the
time zone of the event from a drop-down list using the
time_zone_select helper. This is stored in the events table as a
string.

Because of legacy data which is stored in UTC, I want to keep the
dates and times in the table as UTC but when I display it, I want to
show the abbreviated version of the time zone value as selected.

For example, if the user created an event that starts on: 2009-05-01
10:30:00 UTC
and they chose the time zone: “Mountain Time (US & Canada)”

I want to be able to display it as: May 1st, 2009, 10:30 AM (MST)

What I’m stuck with is: how to easily convert:
“Mountain Time (US & Canada)” => “MST”

Shouldn’t there be an easy mapping somewhere? Given that I have the
full time zone as a string, I need to pass it into a data structure or
object and then get the abbreviation. So far, the best I’ve found is
(where myevent.time_zone is the full time zone string):

ActiveSupport::TimeZone::ZONES.find{|z| z.name ==
myevent.time_zone}.tzinfo.current_period.abbreviation.to_s

This returns “MST”. But there’s gotta be a better way, right? (I just
can’t seem to find one)

Anyone?

-Danimal

You can create a custom reader in your Event model for the start_date
attribute, so that it uses the time zone for this particular event,
something like:

def start_date
@start_date ||= ActiveSupport::TimeWithZone.new(nil, time_zone,
read_attribute(:start_date))
end

This custom reader will override the method generated by ActiveRecord
for time attribute conversion.

Once you’ve done that, the start date will be in the correct zone, and
you can get the zone abbr via strftime %Z, or the #zone method.