Set activerecord default timezone to a specific timezone - ruby-on-rails

I'm using a Rails application to access a database from a legacy application. This application stores all datetime fields using Europe/Madrid timezone.
I tried to set this in my application.rb:
config.time_zone = 'Madrid'
config.active_record.default_timezone = :local
Unfortunately it didn't worked as I expected. It looks like Rails is using the timezone of my system ( America/Sao_Paulo ). So a date that is stored as:
2015-09-09 18:38:01
Will be shown with a difference of 5 hours in Rails:
2015-09-09 23:38:01
Which is the difference between São Paulo and Madrid. It should show 18:38:01 in Rails too since my app's default timezone is Madrid.
Is there a way to force the ActiveRecord timezone without changing my OS timezone?
--- Edit ---
Here is the output that I get:
2.1.3 :004 > Time.zone.name
=> "Madrid"
2.1.3 :005 > LogSent.last.sent_date
LogSent Load (0.4ms) SELECT `log_sent`.* FROM `log_sent` ORDER BY `log_sent`.`id` DESC LIMIT 1
=> Wed, 09 Sep 2015 23:38:01 CEST +02:00
I'm expecting "Wed, 09 Sep 2015 18:38:01 CEST +02:00" which is the value stored in database, in Madrid timezone.

I know this was 3 years ago, but maybe somebody else will have the same question like I did.
When you put config.active_record.default_timezone = :local in your configuration, AR assumes that DB has local timezone, local here meaning the one on your computer. It's pretty hard to change that behaviour, you'd have to monkey-patch both ActiveRecord and ActiveModel.
Trick, however, is to convince Ruby (not Rails) that Madrid is your local time. You can do that by setting TZ environment variable to Madrid.
You can put in your config/initializers/timezone.rb the following
ENV["TZ"] = "Madrid"
Or just set the env variable before running the server as normal,
and don't forget about config.active_record.default_timezone = :local.
This way all values read and written to DB will be in Madrid timezone

How do you save sent_date attribute?
Remember that if you use DateTime.now, it will retrieve the current DateTime of your system (Sao Paulo time). Instead, you should use Time.zone.now, which will retrieve the current DateTime configured in application.rb

Related

Weird Behaviors of datetime(timezone) in Rails application

In our rails 3.2 application, we have configured,
config.time_zone = 'London'
config.active_record.default_timezone = :local
And in postgresql also configured timezone as "Europe/London".
For the past one week, our application datetime field is not working properly with timezone.
For an example, If we create an reminder start_date at 2015-08-18 10AM. it creates `2015-08-18 10:00:00 in postgres database.
when displaying in template,
reminder start date: 2015-08-18 10AM (2015-08-18 10:00:00 +0100 )
BUT,(not always) now frequently its showing UTC time.
reminder start date: 2015-08-18 9AM (2015-08-18 09:00:00 UTC )
it could not be reproduced in development.
If we restart the unicorn server then it is not occurring for 4 hours.
anyone faced this kind of problem?
I fixed this issue, by adding around filter in ApplicationController.
around_filter :use_time_zone
private
def use_time_zone(&block)
Time.use_zone('London', &block)
end
So, whenever the default timezone changed to UTC, it will override and set as BST.

Ruby on Rails / Timezone in config/application.rb seems doesn't work

I'm trying to get a time of users action.
However, it seems return default UTC time even I changed timezone as seoul(UTC +9).
Here are what I did.
in
config/application.rb
put codes as follow.(change default time_zone to seoul)
config.time_zone = 'Seoul'
config.active_record.default_timezone = :local
then, run
rails c
Time.now
I expect time as UTC +9, but it shows UTC +0
Saved time of users action in data is also shown UTC +0.
How can I get time as UTC +9?, is there anything that I need to set?
Try
config.time_zone = 'Korea Time Zone (UTC+09:00)'

Rails: print UTC time by default

I have a non-ActiveRecord server which is sending data to another service. That server expects to receive instructions including UTC in the format: "%Y-%m-%d %H:%M:%S.%L". I already have an time_format.rb initializer that overrides Time::DATE_FORMATS[:default] Is there a way I can configure my server so that Time.now.to_s will by default print UTC time, without me having to specify Time.now.utc every time I call it? I'm using ruby 2.0.0 and Rails 4.
I tried adding config.time_zone = 'London' to config/application.rb but that did not work.
I don't think ActiveRecord should have anything to do with it, but maybe I'm misunderstanding. Like Sergio said, set your applications timezone to UTC.
Here's my Rails app. My computer is in PST. My Rails app is set to UTC.
> Time.now
=> 2014-01-22 21:52:38 -0800
> Time.zone.name
=> "UTC"
> Time.zone.now
=> Thu, 23 Jan 2014 05:52:43 UTC +00:00
> Time.now.utc
=> 2014-01-23 05:52:45 UTC
I would strongly advise not overriding Time.now. That can only lead to the dark side.
A general purpose solution that works for any Ruby application:
module TimeClassExtensions
def now
super.utc
end
end
Time.singleton_class.prepend(TimeClassExtensions)

Model's datetime field is stored differently on heroku from localhost

Steps:
On my localhost server I select the time Jan 18, 2013 10 am - 11 am in my browser located in the Pacific time zone. I then select the exact same time on my production server on heroku.
As you can see the outputs of what is saved to the database are different. I want production to behave as localhost and take into account the timezone when storing the time as UTC. What is causing this? The heroku server is in EST, but that does not account for this behavior.
Controller:
def create
puts params[:event][:starts_at]
#event = Event.create!(params[:event])
puts #event.starts_at
end
Output Localhost:
Fri Jan 18 2013 10:00:00 GMT-0800 (PST)
2013-01-18 18:00:00 UTC
Output Heroku (production):
Fri Jan 18 2013 10:00:00 GMT-0800 (PST)
2013-01-18 10:00:00 UTC
Schema:
t.datetime "starts_at"
Env:
Ruby on Rails 3.2.11
Ruby 1.9.3
Postgres
Background on how PostgreSQL deals with date/time
I think your issue is covered in this answer from another SO question:
Ignoring timezones altogether in Rails and PostgreSQL
Specifically this answer:
https://stackoverflow.com/a/9576170/33204
Use this query for time in UTC format:
SELECT * FROM tbl WHERE time_col > (now() AT TIME ZONE 'UTC')::time
Use this query for time in local timezone:
SELECT * FROM tbl WHERE time_col > now()::time
Rails & ActiveRecords & date/time
This rails/rails github issue also discusses it:
ActiveRecord converts time to default zone on write; assumes UTC on read
There is a comment by pixeltrix which says the following:
#deathbob sorry for the late reply - the accepted values for
config.active_record.default_timezone are either :utc or :local. If
you set it to something other than :utc it will assume :local so what
you're seeing is the expected behavior.
To fix the time in ActiveRecords so that it is always dealt with as UTC you can set the following variable:
config.active_record.default_timezone = :utc
The solution by #slm of config.active_record.default_timezone = :utc did not work for me. Rails was still writing with local and reading with UTC on Heroku.
So I then tried:
config.time_zone = 'Sydney'
config.active_record.default_timezone = :local
Which was still working fine in development but caused the datetime values to now be read in a UTC format from postgres on Heroku.
My temporary workaround solution was to set the default timezone on Heroku with:
heroku config:add TZ="Australia/Sydney"
This is only a temporary solution as I would like my app to use UTC. I have posted to the rails/github issue mentioned by #slm for clarification. I will update my answer when I find a more concrete solution.

Ruby on Rails, delayed_job serializing incorrect datetime as GMT

I have some code that seems to execute improperly when it is serialized and run with delayed_job. To get the necessaries out of the way, I am running Ubuntu 11.04, Ruby 1.8.7 with Rails 3.0.4.
I have a datetime field in one of my tables that obviously stores the date and time of a particular event. In my RoR application, I use this field through the application calling strftime on it to format it in different ways. The output of this formatting is correct on the web page.
I am also using delayed_job to put this same field into an email that is sent out (triggered via some action). When the email arrives, it appears that it has somehow been formatted as GMT. For example, if the date time was supposed to be 11-12-2011 15:30:00 (3:30 PM) in the database, the email would read 11-12-2011 22:30:00 (10:30 PM).
I looked in the database and found somethings that are interesting:
The datetime in the database is 2011-11-12 22:30:00
The app, when displayed via the web, formats the data properly as 11-12-2011, 3:30 PM
The email, formats the data properly as 11-12-2011, 10:30 PM
When I run a small ruby file that simply prints the date and time
p Time.now
I get this the correct output (local, non GMT time)
Mon Aug 15 10:15:27 -0600 2011
When I look at what is in the serialized yaml for the delayed_jobs table, I can see that the date field is formatted as
2011-11-12 22:30:00 Z
In my application.rb, I have
config.time_zone = 'Mountain Time (US & Canada)'
and in my environment.rb, I have
timezone = "Mountain Time (US & Canada)"
Can any one help me figure out what is going on here? I am relatively new to RoR, so this may be a super obvious, easy question. If you need any more debug information, please let me know and I can post it up. Similarly, if my question is unclear, I can try to clar
In my case, I solved explicitly specifying the method in_time_zone in the view
example: #my_obj.created_at.in_time_zone.
I know it is not elegant, but so far I have not found better solutions.
Try changing the date object to a string before serializing.
You may want to set the timezone in the database. If it's MySQL, see: http://dev.mysql.com/doc/refman/5.5/en/time-zone-support.html

Resources