transform time into local time in Ruby on Rails - ruby-on-rails

Right now I have:
Time.strftime("%I:%M%p") which gives me the hr:min AM/PM format which I need. However it's coming back in UTC and I need it local time zone.
How do I change it to local time zone and keep that same format for time?

Also, remember that as of Rails 2.1, Timezones are supported.
in your config/environment.rb file:
config.time_zone = 'UTC'
You can find other values by running
rake time:zones:local
And Ryan Bates has a great railscast on it:
http://railscasts.com/episodes/106-time-zones-in-rails-2-1

Generally that should work. You may have your time-zone set incorrectly, though:
Time.now.strftime("%I:%M%p") # => "12:48PM"
Time.now.utc.strftime("%I:%M%p") # => "04:48PM"
Time.now.utc.getlocal.strftime("%I:%M%p") # => "12:48PM"
Time.now.zone # => "EDT"
This can be affected by the TZ environment variable, your OS locale settings, or your Rails configuration in environment.rb.

Related

Why use Time.current over Time.zone.now in Rails, when Time.zone is always set?

The documentation for Time.current says:
Returns Time.zone.now when Time.zone or config.time_zone are set,
otherwise just returns Time.now.
# File activesupport/lib/active_support/core_ext/time/calculations.rb, line 36
def current
::Time.zone ? ::Time.zone.now : ::Time.now
end
But when is Time.zone ever not set in Rails?
# Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
# Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
# config.time_zone = 'Berlin'
I have commented out config.time_zoneand I still get Time.zone equal to 'UTC' as it apparently sets that by default as the comment mentions. So then, what is the point of using Time.current over Time.zone.now?
PS: I'm observing this on Rails 4.1.16
The short answer is there is no difference except cleaner/shorter syntax if you are using Rails as is.
Time.zone_default gets initialized in ActiveSupport::Railtie via active_support.initialize_time_zone. More info on railtie initialization process here.
My guess for reason of this check is that as a framework it is accounting for situation where someone removed this active_support.initialize_time_zone from their rails boot process. In that case Time.zone would be nil.

How does Rails know my timezone?

How does Rails know my time zone? I don't have it set in application.rb:
# config.time_zone = 'Central Time (US & Canada)'
I searched the whole app for time_zone and that is the only instance of it. I don't see any environment variables for time zone set either. I'm on Windows.
C:\Users\Chloe\workspace\MyBestBody>rails runner "p Time.now"
DL is deprecated, please use Fiddle
2015-06-12 23:38:33 -0400
It prints UTC time when deployed to Heroku.
C:\Users\Chloe\workspace\MyBestBody>heroku run rails console
Running `rails console` attached to terminal... up, run.1949
Loading production environment (Rails 4.2.1)
irb(main):001:0> Time.new
=> 2015-06-13 03:28:34 +0000
Rails 4.2.1
From gettimeofday(), or so the ruby MRI source would have me believe:
int __cdecl
gettimeofday(struct timeval *tv, struct timezone *tz)
{
FILETIME ft;
GetSystemTimeAsFileTime(&ft);
filetime_to_timeval(&ft, tv);
return 0;
}
Per comment, this is a C function, called by the ruby date routines under the hood. You do not call the method yourself, rather you call the ruby methods you are calling.
Your question involves two separate things.
The first is what ruby thinks the time zone is. This is the zone used when you use things likeTime.now or Time.mktime. Ruby uses the C level APIs provided by the operating system to get this information (the TZ environment variable can override this on unixy operating systems).
The second is the time zone your users will see when they use your app. This is frequently not the same thing. Even if your users were all in the same timezone it's a good idea to have your servers use UTC because it is free from things like daylight savings time.
For this reason rails has its own timezone system and the setting you found controls the default value of that timezone. Sometimes you might overwrite this on a per user basis. Rails always records information in UTC, but it will be displayed in views using the value of Time.zone (And input from forms is interpreted in that zone). You can see what the current time in this zone is by doing
Time.zone.now

Rake Time Zones

How would I add a new time zone to the list of time zones?
If I would have to simply add a time zone to my system, why doesn't it appear on the list:
rake time:zones:all
As mentioned by ranja below, I tried to use ActiveSupport with time zones.
So I open up the console
user#host:/var/www/project$ irb
irb(main):001:0> require 'active_support'
=> true
irb(main):002:0>
But what should I use next? And will the new time zone be lost?
How would I implement a permanent new ruby time zone which would be available on all my aps? Thanks so far!
In your rails console type below command , you can get list of name
ActiveSupport::TimeZone.all.map(&:name)
Please try this in application.rb for rails 3.X and enviroment.rb in rails 2.x
config.time_zone = 'Eastern Time (US & Canada)'
after that do
rake time:zones:all
Thanks

Getting local time

I've got this time stored as a string:
2010-07-25 04:16:25
This is the GMT time for some action I took.
Since I live in the Jerusalem time zone, I would like to show it at Jerusalem time, i.e. 07:16 in the morning, not the GMT time of 04:16:25 which is 3 hours before.
How do I properly convert it programmatically with Ruby on Rails? I seem to get lost with the multitude of timezone functions and considerations I need to take when serving users from different locations.
I tried:
Time.parse("2010-07-25 04:16:25")
and it gave me:
"Sun Jul 25 04:16:25 +0300 2010".
I suppose the "+0300" is the difference to where I'm at?
Some light on this, or even a link to a good article that doesn't assume you know much, would help.
You can define your timezone in environment.rb file (if you are using Rails 2.3.*) or application.rb (if you're using Rails 3).
Just look for section about time zones and everything is explained in comment. It will say something like this (this is from Rails 3):
# Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
# Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
# config.time_zone = 'Central Time (US & Canada)'
Just uncomment that last line and you should be fine.
To configure it easily related to your system local zone you can add this in your application.rb
config.time_zone = Time.now.zone
and you can use something like this to get the localtime
Post.created_at.localtime

Under what conditions would I want to set a different application-level timezone in rails?

In almost every environment.rb, there's a line for config.time_zone = 'UTC'.
What exactly does this line do, and under what circumstances would I want to change it (to, e.g., config.time_zone = 'EST')?
Setting config.time_zone changes the default time zone for your Rails application. This is the time zone all times will be displayed in to your users. It is also the time zone it assumes when setting attributes.
However, Rails will always store the times in UTC in the database. The translation happens behind the scenes so (most of the time) you don't have to worry about it.
It's common to change this time zone to one that most of your users will be in. You can run this rake task to see all time zones you can choose from.
rake time:zones:all
It is also very easy to change the current time zone on a per-request basis allowing each user to configure which time zone they are in. here's a before filter example you might add to the application controller.
before_filter :set_user_time_zone
private
def set_user_time_zone
Time.zone = current_user.time_zone if logged_in?
end
See this Railscasts episode for more information.
Just to add one point to Ryan's excellent answer. If you wanted to set it to Eastern Time, it wouldn't be
config.time_zone = 'EST'
it would be
config.time_zone = 'Eastern Time (US & Canada)'
Use one of the following time zones to get the list of available options:
rake time:zones:all
rake time:zones:local
rake time:zones:us

Resources