野ログはノロキュアMaxHeart
2008-11-05
_ TimeのインスタンスをRailsプロジェクト内から撲滅せよ!撲滅せよ!!
ActiveRecordのUTC保存をうまく使うためにはTimeインスタンスを使っていてはけない。
t1 = Time.local(2008, 11, 1) Entry.all(:conditions => ["created_at > ?", t1]) #SELECT * FROM "entries" WHERE (created_at > '2008-11-01 00:00:00') t2 = Time.zone.local(2008, 11, 1) Entry.all(:conditions => ["created_at > ?", t2]) #SELECT * FROM "entries" WHERE (created_at > '2008-10-31 15:00:00') >> Time.now.class => Time >> Time.zone.now.class => ActiveSupport::TimeWithZone
自前でUTCで検索しようとしたらTime#utcメソッドが破壊的で焦った。
ActiveSupport::TimeWithZoneだと破壊的ではなくなってる。
>> t1 = Time.now => Wed Nov 05 16:45:41 +0900 2008 >> t1.utc => Wed Nov 05 07:45:41 UTC 2008 >> t1 => Wed Nov 05 07:45:41 UTC 2008 >> t2 = Time.zone.now => Wed, 05 Nov 2008 16:46:19 JST +09:00 >> t2.utc => Wed Nov 05 07:46:19 UTC 2008 >> t2 => Wed, 05 Nov 2008 16:46:19 JST +09:00
ActiveSupport::TimeWithZoneのこと知らないまま月の最初から最後までを検索しようとするコードを書こうとして
UTC保存されていることを思い出し、とりあえずUTCで検索かけようと思って書いたコードが…
t = Time.local(2008, 11, 1) Entry.all(:conditions => ["created_at >= ? AND created_at <= ?", t.utc, t.end_of_month.utc]) #SELECT * FROM "entries" WHERE (created_at >= '2008-10-31 15:00:00' AND created_at <= '2008-10-31 23:59:59')
意図したものと全く違うSQLががが・・・!
(これはActiveRecordというよりTime#utcのこと理解してなかった問題ですが。)
ActiveSupport::TimeWithZoneを使えば解決。
t = Time.zone.local(2008, 11, 1) Entry.all(:conditions => ["created_at >= ? AND created_at <= ?", t.utc, t.end_of_month.utc]) #SELECT * FROM "entries" WHERE (created_at >= '2008-10-31 15:00:00' AND created_at <= '2008-11-30 14:59:59')
というかutcよぶ必要ないですよ。
t = Time.zone.local(2008, 11, 1) Entry.all(:conditions => ["created_at >= ? AND created_at <= ?", t, t.end_of_month]) #SELECT * FROM "entries" WHERE (created_at >= '2008-10-31 15:00:00' AND created_at <= '2008-11-30 14:59:59')
いちいちutcつけるとか絶対忘れるのでTime使わないように気をつけよう。
[]


ここで言う中身じゃないかもしれませんが・・・ <br>ここしか検索できなくて失礼します。 <br>コピペ運動会が見れなくなってしまいました。 <br>閲覧と※欄でのツッコミを日課としていた私は涙目です <br>例のサーバーの問題でしょうか? <br> <br>復帰を切に望みます <br>ω <br> \(бゝб)/