I was having a bitch of a time trying to set these new TZ aware
attributes from a string. I've added this helper method to my app, and
thought there might be some interest in adding it to the core.
It parses a time string and returns a proper time instance set in the
right zone. I'm calling it Time.parse_with_zone
Thoughts?
module ActiveSupport #:nodoc:
module CoreExtensions #:nodoc:
module Time #:nodoc:
# Enables the use of time calculations within Time itself
module Calculations
module ClassMethods
def parse_with_zone(time_str)
d = parse(time_str)
t = utc_time(d.year, d.month, d.day, d.hour, d.min)
begin
result = zone.local_to_utc(t)
rescue TZInfo::PeriodNotFound
t += 1.hour
retry
end
result.in_time_zone(self.zone)
end
...better docs and a thorough writeup of the new time zone features
coming soon. In the meantime, here's a quick overview of the api:
Rails initializer option for turning on ActiveRecord's automatic time
zone conversions for datetime/timestamp columns, and setting a default
zone for Time.zone (which can be overridden per request, if
necessary):
# No need to set config.active_record.default_timezone when you set
this:
config.time_zone = 'Eastern Time (US & Canada)'
Set Time.zone per request:
class ApplicationController < ActionController::Base
before_filter :set_time_zone
protected
def set_time_zone
Time.zone = current_user.time_zone
end
end
Methods for creating TimeWithZone instances in Time.zone:
Time.zone.local(*values)
Time.zone.at(secs)
Time.zone.parse(str)
Time.zone.now
Time.zone.today #returns a Date instance
Time#in_time_zone
Time#in_time_zone("Alaska") #use this zone instead of Time.zone
Opt out of automatic time zone conversions for specific ActiveRecord
model attributes:
class Task < ActiveRecord::Base
skip_time_zone_conversion_for_attributes = :alert_at, :alert_at2
end
That doesn't work for me because I'm using TZInfo::Timezones
There is no parse for that class AFAIK. Since Rails accepts that as a
zone, it'd be nice if you included that method for those of us stuck
on TZInfo::Timezone.
Unless there's a way to automatically convert that to a Rails TimeZone
object when setting Time.zone? Might be a better idea...
Unless there's a way to automatically convert that to a Rails TimeZone
object when setting Time.zone? Might be a better idea...
That's not a bad idea -- the Time.zone setter method could wrap
TZInfo::Timezone instances in a Rails TimeZone object, and that would
allow you to use parse, local, at, now and today methods, plus any
other methods that we might add to TimeZone instances in the future.
Should be easy enough to implement this.
That would save a ton of headaches. A lot of these issues I've run
into seem to be because of TZInfo::LinkedTimezone / TZInfo::Timezone.
Wrapping that class would be beautiful.
I'd make the switch to TimeZone but I can't seem to find a proper
translation for the identifier strings already stored in my DB. I'm
willing to bet a lot of other people are in the same boat.
I'd make the switch to TimeZone but I can't seem to find a proper
translation for the identifier strings already stored in my DB. I'm
willing to bet a lot of other people are in the same boat.
You can find the mapping between TimeZone and TZInfo indentifiers in
the TimeZone::MAPPING hash. Converting over should be straightforward,
just be aware of the following:
1. TZInfo defines more zones than TimeZone does, so some TZInfo
identifiers have no TimeZone equivalent
2. some TZInfo identifiers map to more than one TimeZone (e.g.,
"America/Mexico_City" maps to both "Guadalajara" and "Mexico City")
That would save a ton of headaches. A lot of these issues I've run
into seem to be because of TZInfo::LinkedTimezone / TZInfo::Timezone.
Wrapping that class would be beautiful.
Added in [9107] -- in addition to recognizing Rails TimeZone instances
and identifiers, Time.zone= now accepts a TZInfo::Timezone instance,
or a TZInfo/Olson identifier string (e.g., "America/New_York").
TZInfo::Timezones are then wrapped on the fly in a Rails TimeZone.
Glad you're putting the new time zone features through the paces --
keep us posted if you run into any more issues.
Not sure where this comment should go, but a fresh rails command
generates a configuration in environment.rb that attempts :timezone=
on the Rails::Configuration object. (NoMethodError)
Result: rails does not generate a working app!
Hi Chris:
Thanks for your reply, but I'm afraid I don't understand:
If I do:
1> gem install rails #( rails (2.0.2.9129)
2> rails mysite
3> cd mysite
4> (placeholder)
5> ruby script\about
(NoMethodError)
but if I insert in placeholder
4> rake rails:freeze:edge
I get a good result?
But why should the generator packed with the gem, generate edge-only
code?
I didn't really want to run on the edge.
Why would the gem-generator anticipate an edge installation?