昔の Ruby On Rails のブログ

注意! RoR2 とかの話です。今は更新していません。昔、はてなダイアリーで書いていたブログを移行しました。

Timezone の扱い

http://railscasts.com/episodes/103-site-wide-announcements に以下のようなロジックがあります。

def self.current_announcements(hide_time)
  with_scope :find => { :conditions => "starts_at <= now() AND ends_at >= now()" } do
    if hide_time.nil?
      find(:all)
    else
      find(:all, :conditions => ["updated_at > ? OR starts_at > ?", hide_time, hide_time])
    end
  end
end

このロジックの日時の部分でハマりました。
Timezoneの扱いです。

私の理解では

  • config.time_zone = 'Tokyo' としてもしなくてもDBには UTC で記録される
  • config.time_zone = 'Tokyo' とすると、Rails 経由だとよきに計らってくれる
  • "starts_at <= now() ..." と ["starts_at <= ? ...", Time.now] はどっちも、期待する結果になりません

今のところ…

["starts_at <= ? ...", Time.now - 9.hour]

というダサいコードになっています orz
上記だと hide_time も時間差注意ですね。


ちなみに now() は MySQL ではOKだけど、SQLite3 ではNGでした。
あと、デバッグは console で

ActiveRecord::Base.logger = Logger.new(STDOUT) 

するとSQL文が展開表示されるので Goodです。