Search code examples
rubytimezonepadrino

Setting up Time.zone in Padrino


I am having a trouble setting the default ActiveSupport::TimeZone in my padrino project.

In my boot.rb I have

Padrino.after_load do
  Time.zone = 'UTC'
  ActiveRecord::Base.default_timezone = :utc
end

My controller file has:

MyApp::App.controllers :post do
  get :index do
    puts Time.zone # this returns nil
    render 'index'
  end
end

When I hit the index action I get nil for Time.zone. It seems as though something might be overwriting Time.zone or it isn't loaded properly.

  • I am able to print out the Timezone after setting it in boot.rb. So I know it was set.

Solution

  • You can set it like this:

    Time.zone_default = Time.find_zone!("UTC")
    

    That's all you need, but see below for details.

    The above worked for me with activesupport 5.0.2. I looked at how Time.zone is implemented:

    class Time
      include DateAndTime::Zones
      class << self
        attr_accessor :zone_default
    
        # Returns the TimeZone for the current request, if this has been set (via Time.zone=).
        # If <tt>Time.zone</tt> has not been set for the current request, returns the TimeZone specified in <tt>config.time_zone</tt>.
        def zone
          Thread.current[:time_zone] || zone_default
        end
    

    I then guessed that it might be missing in the current thread with Padrino.

    Presumably Time.zone would need to be set once for each thread. For whatever reason, that's not always the case when assigning the zone in Padrino.before_load. I did not dig into this, but I'm sure there's a nicer solution to be found that assigns it in each thread.

    If you want per-user time zones, not just a global one for the entire app, you will need to dig further.