I'm trying to get some timezone stuff working in my app (rails 2.0.2), and from what I've read it looks like TzTime can help out with this, so... I've got things set up the way I think I'm supposed to:
- database and rails app running in UTC - freshly updated tzinfo gem - freshly installed tzinfo_timezone and tztime plugins. - time_zone field in users table - canonical :composed_of tz field in User model - canonical around_filter that sets TzTime.zone based on the current User - used tz_time_attributes to do magic for one field ("starts_at") in a model
So far, so good. If I simply display a "starts_at" value in a template in a normal way, it correctly does the timezone translation.
Now for the troubles:
- the magic that tz_time_attributes provides for converting a field from utc to local (when reading the value) works by creating a getter. However, some rails constructs seem to bypass the getter! For example if I'm inside a fields_for (which in turn is inside a form_for), and I do something like "f.text_field :starts_at", the getter isn't called, and no conversion is done; I assume it's calling read_attribute directly. Damn! The obvious workaround of grabbing the field and constructing an input element myself is ugly, and goes against the whole point of using TzTime in the first place.
- the magic that tz_time_attributes provides for converting a field from local to utc (when writing the value) works by creating a before_validation filter. This filter checks the attribute to see if it acts_like a Time or Date instance, and hasn't already been converted to utc. However, if the value coming into the field is coming from a form, chances are that at this stage it's still a string, not a Time or Date, so it won't be converted before being saved! The obvious workaround here is to massage the value in the controller action before it's saved, turning it into a Time or TzTime, but that's also kind of a pain.