Time Zones
Geplaatst door Michiel de Mare do, 28 mei 2009 21:28:00 GMT
Tijdfuncties in Rails zijn op sommige punten nogal wankel. Zo zou je verwachten dat Time.now
en 0.seconds.ago
gelijk zijn. Dat is niet zo:
>> Time.now
=> Thu May 28 23:28:37 +0200 2009
>> 0.seconds.ago
=> Thu, 28 May 2009 23:28:42 CEST +02:00
Nadere inspectie leert dat Time.now
een normaal Ruby Time
instantie is, terwijl 0.seconds.ago
een ActiveSupport::TimeWithZone
object is.
>> Time.now.to_s(:db)
=> "2009-05-28 23:33:08"
>> 0.seconds.ago.to_s(:db)
=> "2009-05-28 21:33:16"
De to_s(:db) method wordt gebruikt in find queries en named scopes, en bovenstaand verschil maakt dat het gebruik van Time.now
, Time.parse
en Time.at
af te raden is wanneer het als database-parameter gebruikt kan worden. Rails converteert Time
instanties wel in TimeWithZone
objecten bij ActiveRecord-attributen. Als alternatief kan Time.zone.now
etc. gebruikt worden.
u.published_at = Time.now
werkt prima, maar wanneer je in je environment.rb een lokale tijdzone hebt staan, gaat dit verkeerd in Rails 2.3.2:
named_scope :begun, proc{{:conditions => ['started_at < ?', Time.now]}}
Weest op uw hoede!
Daarom heeft Rails Time.current toegevoegd aan de Time class, wat de zone wel in rekening brengt en dus nu de voorkeur heeft.
Aha! Bedankt voor de tip. Ik blijf het echter een verschrikkelijk lelijke hack vinden. En wat ik niet begrijp is waarom het niet werkt voor
Time.now
:Daarnaast werkt dit nog steeds heel raar:
Oh, dat is inderdaad wel nasty! Gelukkig nog geen last van gehad, maar goed om te weten. Thanks!
>> Time.now.to_i.is_a?(ActiveSupport::Duration) #=> false >> 1.day.is_a?(ActiveSupport::Duration) #=> true
Matthijs: Ik weet waarom het komt, maar
1.day
lijkt, op een integer, beweert dat het een integer is, was vroeger een integer, maar wanneer je er een andere integer door deelt krijg je eenfloat
. Mijns inziens is dat gewoon een bug.