Rails 3 ActiveRecord Time.now issue - ruby-on-rails

I have
Rails 3.0.9
Activerecord-sqlserver-adapter 3.0.15
TinyTds
MSSQL 2005
I have a problem with using Time.now.
That is what I do in console:
Could someone explain this behavior?
irb(main):026:0> row = Eclaim.where(:id => 1).first
=> #<Eclaim id: 1, id_user: 1, property: "inv", app_number: nil, patent_number:
nil, native_number: nil, title: nil, applicants: nil, receive_date: nil, change_
date: "2012-05-08 10:20:44">
irb(main):027:0> row[:change_date] = Time.now
=> 2012-05-08 13:37:13 +0300
irb(main):028:0> row.save
=> true
irb(main):029:0> row = Eclaim.where(:id => 1).first
=> #<Eclaim id: 1, id_user: 1, property: "inv", app_number: nil, patent_number:
nil, native_number: nil, title: nil, applicants: nil, receive_date: nil, change_
date: "2012-05-08 10:37:13">
irb(main):047:0> Time.zone
=> (GMT+00:00) UTC
Why am I getting the date 2012-05-08 10:37:13 in database instead of being 2012-05-08 13:37:13 +0300?

I have found the solution:
In application.rb you should write such settings:
config.time_zone = 'Riga'
config.active_record.default_timezone = :local

ActiveRecord stores dates in UTC (previously known as GMT). It converts the dates back to the local time zone when you format the date. After Eclaim.where(:id => 1).first, do a row.change_date.
irb(main):029:0> row = Eclaim.where(:id => 1).first
irb(main):029:0> row.change_date

i am not an expert in dates, but what happens if you change to utc like this
> row[:change_date] = Time.now.localtime
> row.save
I think that will give the correct result. As to why this happens(my 2 cents):
One should always store the dates in some standard(people seem to differ as to what format that is). However just be aware that when storing as utc time, you will need to display the time as local time(easily done). In your example above rails is automatically converting to utc and storing it. Hope it helps
EDIT
Rails i think still defaults to utc time(not sure how to change this). However from utc time in database you could call localtime.What happens if you call this
Eclaim.first.change_date.localtime
This is the only way i can think off to get the localtime from utc stored in database.

Related

Rails app not following the timezone configured in config/application.rb

I'm new to configuring timezones and confused about a few points. Any advice on the correct configuration would be appreciated.
My understanding is that it's best practice to store all timestamps as UTC in the DB (I'm using PostgreSQL). On the other hand, in the actual app, I'd like to see the timestamps in my local timezone (JST +9:00).
I've configured config/application.rb like this:
module MyApp
class Application < Rails::Application
config.load_defaults 5.2
config.time_zone = 'Tokyo'
end
end
However, I'm not sure it's configured correctly, because I'm getting mixed results in the rails console. Time.zone and Time.now tell me the timezone is set to JST, but the created_at and updated_at timestamps are rendered as UTC when I do User.first.
User.first
#=> #<User id: 1, first_name: "Bob", last_name: "Smith", created_at: "2019-04-09 08:54:30", updated_at: "2019-04-09 08:54:30">
But then, the time is rendered as JST if I specifically ask for the created_at time:
User.first.created_at
#=> Tue, 09 Apr 2019 17:54:30 JST +09:00
Why are the timestamps being rendered as UTC unless I specifically ask for the time itself? Is this normal? The same phenomenon is happening for DateTime columns in my other tables as well.
All your dates seems to be the same, it's just how they are represented on different contexts.
This:
User.first
#=> #<User id: 1, first_name: "Bob", last_name: "Smith", created_at: "2019-04-09 08:54:30", updated_at: "2019-04-09 08:54:30">
renders the result of .inspect
This:
User.first.created_at
#=> Tue, 09 Apr 2019 17:54:30 JST +09:00
is the console guessing you want the date formated with the current time zone.
You could force some representation being explicit
User.first.created_at.to_formatted_s(:db) #should print the same as you see on the inspect
I18n.localize(User.first.created_at) #should localize the date with the default date format
I18n.localize(USer.first.created_at, format: :something) #should localize the date as the format you defined as ":something" on your locale file

Ruby on Rails timezone storing different timezones to datetime attributes

I have a model "Request", that have the common attributes created_at and updated_at, but have others datetime attributes: "inserted_at" and "response_deadline". My problem is especially with response_deadline, that sometimes is stored with the correct timezone and other times with a different one (wtf??), and in other cases, response_deadline with the same timezone's giving a correct datetime and the other a wrong datetime.
My application.rb is configured with the correct timezone:
config.time_zone = 'Brasilia'
and I already tried change the AR default timezone:
config.active_record.default_timezone = :utc or :local
Other problem is that if I put :local the problem in response_deadline is solved, but the other datetime attributes get wrong.
The server timezone and date are correct too.
Sometimes the response_deadline is stored like that:
response_deadline: "2018-11-01 02:00:00" - WRONG
and other like that:
response_deadline: "2018-11-01 03:00:00" - CORRECT
And the strangiest behavior, two apparently wrong timezones:
response_deadline: "2018-11-09 02:00:00" - WRONG
response_deadline: "2018-10-30 02:00:00" - CORRECT?
but when I run in rails c:
2.3.0 :002 > request1.response_deadline
=> Thu, 08 Nov 2018 23:00:00 -03 -03:00
2.3.0 :002 > request2.response_deadline
=> Tue, 30 Out 2018 00:00:00 -02 -02:00
The data are taken from a CSV file (uploaded), and the response_deadline has this format:
29/10/2018 23:59:59
Controller snippet:
uploaded_file = params[:file]
unsaved = []
begin
sheet = RubyXL::Parser.parse(uploaded_file.tempfile.path)
dados = sheet[0]
demandas = []
(4...(dados.sheet_data.rows.size - 1)).each do |num|
if !dados.sheet_data.rows[num][1].nil?
request_type = RequestType.has_request_type? dados.sheet_data.rows[num][3].value,Request.sources[:ouv]
demanda = {
protocol: dados.sheet_data.rows[num][2].value,
source_cd: Request.sources[:ouv],
request_type_id: request_type,
created_at: dados.sheet_data.rows[num][7].value,
inserted_at: Time.now,
response_deadline: dados.sheet_data.rows[num][8].value,
requester_name: dados.sheet_data.rows[num][21].value.blank? ? "AnĂ´nimo" : dados.sheet_data.rows[num][21].value,
hide_requester_information: nil,
all_completed_information: false
}
demandas << demanda
end
end
count = 0
demandas.each_with_index do |demanda, index|
request = Request.new(demanda)
request.requester = Requester.where(name: "eouv").take
if request.valid? && !request.request_type_id.nil?
if request.save
...
Why?? I really wanna understand what is happening... =/
All the attributes are datetime, including :response_deadline of course.
Environment:
This is happen only in the production enviroment, the DB is Oracle 12c, running on a RHEL 6.
Ruby 2.3.0 and Rails 4.2.1
Someone could help to try indetify what is going on?
ps:some days ago this was not happening.

Rails and timezone in created_at

ruby-1.9.2-p0 > SalesData.last
=> #<SalesData id: 196347, created_at: "2011-04-05 18:53:15", updated_at: "2011-04-05 18:53:15">
ruby-1.9.2-p0 > SalesData.last.created_at
=> Tue, 05 Apr 2011 20:53:21 CEST +02:00
application.rb:
config.time_zone = 'Copenhagen'
I don't get it - anyone?
I assume you're asking why the created_at datetimestamps appear to differ. In short, they don't.
Rails always stores datetimes in UTC, converting them to your configured timezone on the fly while loading the record. I don't know exactly when that conversion happens, but I'm betting you're just seeing those two states.

Time fields in Rails coming back blank

I have a simple Rails 3.b1 (Ruby 1.9.1) application running on Sqlite3. I have this table:
create_table :time_tests do |t|
t.time :time
end
And I see this behavior:
irb(main):001:0> tt = TimeTest.new
=> #<TimeTest id: nil, time: nil>
irb(main):002:0> tt.time = Time.zone.now
=> Mon, 03 May 2010 20:13:21 UTC +00:00
irb(main):003:0> tt.save
=> true
irb(main):004:0> TimeTest.find(:first)
=> #<TimeTest id: 1, time: "2000-01-01 20:13:21">
So, the time is coming back blank. Checking the table, the data looks OK:
sqlite> select * from time_tests;
1|2010-05-03 20:13:21.774741
I guess it's on the retrieval part? What's going on here?
Technically, it's not coming back blank. It comes back as a time with a default date. It returns 2000-01-01 20:13:21 as the time, which is expected.
Rails is doing some magic loading of the data into a Time object and clearing out the date (since you only told it to store the time).
If you want to store the date and time then you need to define the column as a datetime. And conversely, if you wanted just a date you would use date.
So to recap:
date => "2010-12-12 00:00:00"
time => "2000-01-01 13:14:15"
datetime => "2010-12-12 13:14:15"

Weird created_at behavior

I've set config.time_zone = 'UTC' in environment.rb, and yet still I get some weird behavior with Rails' built-in datetime fields:
>> Time.now
=> Sun Jun 21 17:05:59 -0700 2009
>> Feedback.create(:body => "testing")
=> #<Feedback id: 23, body: "testing", email_address: nil, name: nil, created_at: "2009-06-22 00:06:09", updated_at: "2009-06-22 00:06:09">
>> Time.parse(Feedback.last.created_at.to_s)
=> Mon Jun 22 00:06:09 UTC 2009
Any thoughts?
It looks like it's properly setting the timezone in the ActiveRecord object, so I don't think you need to worry too much. If you want to force your timestamp from Rails to use UTC, you can use Time.utc.
Time.now.utc
=> Mon Jun 22 00:54:21 UTC 2009

Resources