Changing a time’s zone in Rails, keeping the same local representation – a post at Steven Luscher’s blog

Photo credit

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.

Tags: ,

be the first person to comment on this post:

Want to include some code? Use Pastie and stick the link into your comment. Linebreaks, block quotes, and preformatted code blocks will be removed.

Please make an attempt to prove that you’re still human before submitting your comment.

If you've written a post of your own in response to this one, feel free to trackback from your own site.

be the first person to comment on this entry.