Set timezone from user in ApplicationController

Hi,

when setting the timezone from a user in the ApplicationController, if found the following Code:

class ApplicationController < ActionController::Base
  around_action :set_time_zone

  private
    def set_time_zone
      Time.use_zone(current_user.timezone) { yield }
    end
end

Source: Time (rubyonrails.org)

But could I also just set Time.zone in a before_action like this:

class ApplicationController < ActionController::Base
  before_action :set_time_zone

  private
    def set_time_zone
      Time.zone = current_user.timezone
    end
end

Why should the timezone be set always back to it’s original state? Is there any advantage/disadvantage? Rails is reading and writing all timestamps to UTC in the database, no matter what is set in Time.zone.

Maybe someone could give me a good advise.

It may not matter most of the time, but sometimes corner cases are relevant.

There is always some time zone set. UTC is the default although you can configure a different default if you want. Ideally your default is just a fallback. Ideally you are setting the time zone for the duration of the request based on what is most useful to the person making the request. This is what either your around_action or before_action do. Both will successfully do that but only one will put it back to the default when the request is done.

Most of the time this lack of cleanup won’t matter as the very next request will also assign the request-relevant timezone overwriting whatever was there before. But what if some controller doesn’t inherit from ApplicationController? Or what if a request is not handled by a controller at all but instead Rack middleware?

Whatever the scenario, corner cases like this may assume the time zone is on the default not realizing the last request didn’t cleanup itself. Cleaning up like this just keeps things more predictable. You don’t end up with odd scenarios that occur once in a while only when a series of certain actions happen.

1 Like

@e_a Thank you for your nice explanation. So I will choose the clean way and set the timezone back to it’s original state, when the request is done :slight_smile: