The TimeWithZone class in Rails is great to work with, but I found it to be missing one thing. I needed a method for those “whoops, I meant 3:00am PST” moments.
Let’s say that you’ve ended up with a time like March 8 2009 03:00 UTC, where you meant to say PDT instead of UTC. Wouldn’t it be nice to be able to change only the zone part of the time, without changing the local representation, like so:
>> t = Time.zone.parse('March 8 3am') => Sun, 08 Mar 2009 03:00:00 UTC +00:00 >> t.zone = 'America/Los_Angeles' => "America/Los_Angeles" >> t # It's 3:00am in Vancouver! => Sun, 08 Mar 2009 03:00:00 PDT -07:00 >> t.zone = 'America/Denver'; t # It's 3:00am in Edmonton! => Sun, 08 Mar 2009 03:00:00 MDT -06:00 >> t.zone = 'Saskatchewan'; t # It's 3:00am everywhere! => Sun, 08 Mar 2009 03:00:00 CST -06:00
You can, if you add this method to ActiveSupport::TimeWithZone:
module ActiveSupport class TimeWithZone def zone=(new_zone = ::Time.zone) # Reinitialize with the new zone and the local time initialize(nil, ::Time.__send__(:get_zone, new_zone), time) end end end
In my application, my users set start and end times for their events. I was able to make use of this new zone= method when they choose a new time zone for their event; it lets me preserve the local representation of the existing start and end times between time zone changes.





