Why doesn't `config.time_zone` seem to do anything? - ruby-on-rails

In application.rb, it says:
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.
But setting config.time_zone = 'Central Time (US & Canada)' or config.time_zone = 'Eastern Time (US & Canada)' has no effect - the created_at field in a model is stil being saved in UTC.
According to this railsforum answer:
config.time_zone just lets rails know
that your server is set to this
timezone so when it writes dates to
the database it can properly convert
it to UTC.
If that is true, then why is it that when my system time is Pacific Time (US & Canada) and config.time_zone = 'Central Time (US & Canada)' or config.time_zone = 'Eastern Time (US & Canada)', that the created_at time is the correct UTC? Should it not be incorrect?!
Because, if the PST time is 8 PM, then EST is 11 PM and UTC is 4 AM.
Presuming that Rails does Time.now, that would be 8 PM. And we told Rails that the server is in EST. So, 8 PM would be EST time as far as Rails is concerned and the UTC would then be 5 AM UTC, which would be incorrect (because the actual time is 8 PM PST/11 PM EST, which is 4 AM UTC)
What's going on here?

Here's a list of concepts and things that may help you:
config.time_zone doesn't set "Server Time", that is controlled by your operating system usually.
Rails always stores your dates in UTC in the database (unless you change a different setting).
Time.now returns the localtime for your computer in your timezone and it also includes the local timezone offset from your operating system, which means Ruby and therefore Rails knows how to convert localtime into UTC. You can try this by using irb directly, so no Rails libraries are loaded:
ctcherry$ irb
>> Time.now
=> Mon Feb 21 20:53:14 -0800 2011
>>
If config.time_zone, or Time.zone is set, to lets say EST, Rails expects that if you set a datetime attribute that you mean for that time and date to be in specified timezone, in this case EST. This is why you set Time.zone equal to your end users timezone, so they can use their local time and dates, and you can pass them directly into your ActiveRecord models and Rails can convert it to UTC for storage in the database.
Does that help at all?

You need to use in_time_zone (i.e. Time.now.in_time_zone) to get some something other than UTC.

Related

use table's timestamp column(without timezone) as EST

I have a table 'A' in db which have a column 'x' of type 'timestamp without timezone' and in rails project I have set timezone to 'EST'. Everything works fine when I create/update record from my project.
The problem is that I imported data from another DB using PSQL. 'x' column have the same time as in old DB but when I use 'ActiveRecord' query, I get '+05:00' offset. I am confused how to tell 'ActiveRecord' that that time is already in 'EST'?
here is a solution by me.
=> A.first.x.to_s(:db)
# "1900-01-01 21:47:00"
=> A.first.x
#Mon, 01 Jan 1900 16:47:00 EST -05:00
but is there any other better option ?
Adding following to application.rb must work
config.time_zone = 'Eastern Time (US & Canada)'
config.active_record.default_timezone = 'Eastern Time (US & Canada)'
or Every zone you wish
You can convert your time in 'EST' time zone in your query.
You can find your answer here

Rails 4 - how to set a timezone for strftime?

Every user in our database can select his/her own timezone. The default timezone of our application Eastern Time:
config.time_zone = 'Eastern Time (US & Canada)'
config.active_record.default_timezone = 'Eastern Time (US & Canada)'
When I display some dates/times in the application, I usually use for that purpose .strftime. How can I give a parameter to strftime to display the date/time properly (in the given timezone for the specific user)?
Or is there a better way than to format every date/time with using strftime?
EDIT:
Every user has a time_zone string column, where is stored the timezone like this: "Eastern Time (US & Canada)".
As the every date/time will be re-calculated for every timezone, how about the performance? Will this not slow down too much rendering views?
Set your time object in_time_zone() before strftime.
Say you're displaying created_at, you'd do:
object.created_at.in_time_zone(current_user.timezone).strftime("...")

How to set the timezone to EST throughout the rails app?

I want to use EST throughout the app. I have set the
config.time_zone = 'Eastern Time (US & Canada)'
config.active_record.default_timezone = 'Eastern Time (US & Canada)'
what I want is, I have to get all the time I have used like "DateTime.now" and it now returns time in my local timezone but I want it to return date time in EST. Also I have date time range picker and I get the start date and end date and parse the string to time using
(params[:start_date]).to_time
which also returns the date time in local zone and instead i want all those to return in EST. How can I do this? Any help is appreciated.
Thanks in advance.
DateTime.now and Time.now doesn't respect Time.zone and will always use the server time. If the machine you're using is set to a different timezone, these 2 will use that timezone.
to_time on the other hand defaults to local timezone as mentioned in apidock (although just tried this out and I get utc by default). To get these times in the timezone set, append in_time_zone
DateTime.now.in_time_zone
Time.now.in_time_zone
string.to_time.in_time_zone
There are some shortcuts for these though. The following code will return the timestamps in the current timezone
Time.zone.now
Time.zone.parse(string)
Normally, in database date-time would be saved in UTC format unless you have selected a specific TimeZone for Active Record and it would be easier if you have to meddle with multiple TimeZones. But, while you access the values you will get the values in you selected TimeZone.
config.time_zone = 'Eastern Time (US & Canada)
Now, suppose you have a datetime value in UTC from table as
datetime1 = "2014-08-25 10:25:57 +0000"
You can convert it to the selected timezone 'Eastern Time (US & Canada)' as below,
Time.zone.parse(datetime1) => Mon, 25 Aug 2014 06:25:57 EDT -04:00
Then, if you need it in a proper format, use method strftime.
Time.zone.parse("2014-08-25 10:25:57 +0000").strftime("%d-%m-%Y %H:%M:%S") => "25-08-2014 06:25:57"
Hoep it helps :)

Different date saved to database - wrong time zone

When I fetch a date from FullCalendar with Javascript I have the following values:
Fri Sep 13 2013 08:30:33 GMT-0400 (EDT)
After I save that date to database I see that in database there are different values:
2013-09-13 12:00:00.000000
So, date is automatically converted to UTC and saved like that into database. How to save the correct date into database? I don't want to hardcode it :)
Thank you.
For that you need to define your time zone in your application.rb
config.time_zone = 'YOUR-TIME-ZONE'
config.active_record.default_timezone = :local
config.active_record.time_zone_aware_attributes = false
By default, the rails app timezone is UTC. Whenever the record is saved the date, datetime, time fields are saved with DB's timezone but when they are fetched back in models it is converted back to UTC.
So, in your case set your application timezone in application.rb like this
config.time_zone = 'Central Time (US & Canada)'
Now, whenever the records are fetched from database it will always be converted to CST timezone irrespective of DBs timezone.
Hope this will help.

Time.now & Created_at are different? Ruby on Rails

My site is deployed on heroku. Time.now will return today, but the created_at field of a record (created right now) will say its tomorrow. I assume this has to do with server time?
Is there a way to make sure they're the same?
Best,
Elliot
Update so I did this "heroku rake time:zones:us"
it gave me:
* UTC -10:00 *
Hawaii
* UTC -09:00 *
Alaska
* UTC -08:00 *
Pacific Time (US & Canada)
* UTC -07:00 *
Arizona
Mountain Time (US & Canada)
* UTC -06:00 *
Central Time (US & Canada)
* UTC -05:00 *
Eastern Time (US & Canada)
Indiana (East)
however, when I set config.time_zone = 'UTC -05:00' in my environment, the app fails to start. any ideas?
Rails always stores UTC time on the database; the created_at field by itself should be offset by exactly your timezone's variation relative to UTC.
Whenever you load a record in your application, the fields get converted to the timezone specified in environment.rb. It might have something like this:
config.time_zone = 'UTC'
For the time to be converted properly to your timezone, you might change this configuration setting to one matching your actual time zone. For instance:
config.time_zone = 'Central Time (US & Canada)'
To see available zones, issue "rake -D time" on your rails directory. This will give you instructions on how to get time zone names for use in configuration.
To add onto Roadmaster's answer, I had a similar challenge: the normal Rails timestamps were stored based on UTC in the database, but I needed to query to find all records created today according to the local time zone.
The query looked like this:
completions.where("created_at BETWEEN ? AND ?",
Date.today, Date.today + 1.day).count >= 1
I fixed this by calling #to_time on the dates, as follows. This converted them into a timestamp having the proper time zone, and the correct records were fetched in the database, effectively making the query timezone-aware.
completions.where("created_at BETWEEN ? AND ?",
Date.today.to_time, Date.today.to_time + 1.day).count >= 1
Just need to uncomment and change to the time zone you wanna.
If you want to check all the time zone, run rake time:zones:all and will output a list.
config/Application.rb
module Clerk
class Application < Rails::Application
# Settings in config/environments/* take precedence over those specified here.
# Application configuration should go into files in config/initializers
# -- all .rb files in that directory are automatically loaded.
# 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 = 'La Paz'
# The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
# config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
# config.i18n.default_locale = :de
end
end
I added the following to lines of code. I wanted the created_at to be on the ActiveRecord data creation.
config/Application.rb
module RailsApp
class Application < Rails::Application
config.time_zone = 'Pacific Time (US & Canada)'
config.active_record.default_timezone = 'Pacific Time (US & Canada)'
end
end

Resources