0

Hello i am working on a rails project. i want the time with specific zone, i know i can use Time.zone.now but i want to first set the zone and then want to get the time based on the zone. is there any way so that i can override the Time.now method with Time.zone.now after setting the zone.

I have tried to create a before action in application_controller.rb and then define the zone, but whenever i am trying to access Time.now its always returns the time without time zone. please help me. Thanx in advance.

application_controller.rb
def set_current_time_zone
  Time.zone = current_user.time_zone unless current_user.blank?
end
awsm sid
  • 595
  • 11
  • 28
  • In `Time` class, override `now` method or, just add `with_timezone` method which returns `timezone.now` -)) – marmeladze Feb 21 '18 at 18:33

3 Answers3

3

Why not use Time.current? It will give you time with timezone if you have the zone set in config.zone or Time.zone.

See the example:

2.5.0 :021 > Time.zone = "Tallinn"
  => "Tallinn" 
2.5.0 :022 > Time.current
  => Wed, 21 Feb 2018 20:37:29 EET +02:00 
2.5.0 :023 > Time.zone = "New Delhi"
  => "New Delhi" 
2.5.0 :024 > Time.current
  => Thu, 22 Feb 2018 00:07:38 IST +05:30 

See the corresponding apidock about .current method and a good article in thoughtbot about Ruby timezones.

Andres
  • 2,099
  • 3
  • 22
  • 39
  • yes bro i agree but i dont want to change Time.now to Time.current i want to overirde Time.now so that i don't have to change anywhere. – awsm sid Feb 22 '18 at 05:16
2

Hope this will help

module TimeOverride
  # overriding time to return time accoring to the application configured 
  #  timezone
  # instead of utc timezone
  def now
    super.getlocal(Time.zone.utc_offset)
  end
end

module DateTimeOverride
  # overriding time to return time accoring to the application configured 
  #timezone
  # instead of utc timezone
  def now
    Time.now.to_datetime
  end
end

Time.singleton_class.send(:prepend, TimeOverride)
DateTime.singleton_class.send(:prepend, DateTimeOverride)
hsaini734
  • 33
  • 1
  • 7
1

This is how I do it, following Ryan Bates' railscast at: http://railscasts.com/episodes/106-time-zones-revised

class ApplicationController < ActionController::Base

  around_action :set_time_zone, if: :current_user

  def set_time_zone(&block)
    Time.use_zone(current_user.time_zone, &block)
  end

end

The use_zone method expects a block and sets the time zone for the duration of that block. The original time zone is set back when the request completes.

Then, I can use Time.zone.now and it will always use the correct time_zone set for the user (the time_zone method returns the time zone the user has configured in his settings or UTC). All date and time fields in forms are also treated in current user's time zone when processed in the controller or model.

Pablo
  • 3,004
  • 1
  • 12
  • 19
  • yes i have implement the same but the project is too big and i can't replace Time.now to Time.zone.now. i want to override Time.now to Time.zone.now so that i dont have to change everywhere – awsm sid Feb 22 '18 at 05:14
  • @awsmsid You're creating a nightmare for anybody else joining the project if you monkey patch a ruby core library to produce different behaviour. Don't do that. Just grep the entire project with your IDE and replace all instances of `Time.now` to `Time.zone.now`. – Kelsey Hannan Jan 20 '21 at 23:33