Using default application timezone with DateTime.strptime in Rails 5 - ruby-on-rails

I read similar questions but did not find a solution.
My Rails 5 App is in
'America/Sao_Paulo'
time zone but saves all times in UTC to the database.
When saving a datetime
'2017-01-01 19:00:00'
to my database it will convert it to UTC and save the UTS time to the database.
Now I need to convert a string to datetime using:
DateTime.strptime(date + ' ' + time, '%d/%m/%Y %H:%M:%S')
And this will take the date and time values as they are and save them to the database without converting to UTC. How can I let my app know that my the datetime is not in UTC yet?

ActiveRecord (by default) will save any datetime to UTC. So, in my opinion you don't need to worry if the time in the database isn't yet in UTC, because ActiveRecord will convert it to UTC.
So, when saving to database, ActiveRecord will always convert it to UTC (whether it is in UTC or not).
And when fetching from database, it follows your configuration in config/application.rb
You can find in the file config.time_zone = 'YOUR_TIMEZONE'.
Reference:
http://api.rubyonrails.org/classes/ActiveRecord/Timestamp.html
Hope it helps, cheers!

Related

Converting a UTC date string into a localized date string in Ruby or Rails

I have a date, saved as a string:
my_utc_date_str = "2019-09-15T20:42:15"
This is saved as a UTC date string
My local zone, is:
America/Los_Angeles
What I would like to get is:
2019-09-15 13:42:15
Which is that UTC date, localized to USA Pacific Time Zone.
I tried various combinations of DateTime, Time and Date, with no luck. Any ideas bow to do this, without changing the Time Zone for the session?
Time.zone.parse("2019-09-15T20:42:15")
.in_time_zone("America/Los_Angeles")
.strftime("%Y-%m-%d %H:%M:%S")
# => "2019-09-15 13:42:15"
See ActiveSupport::TimeWithZone for the ActiveSupport extension to Rubys time and date objects and ActiveSupport::TimeZone for a list of time zone mappings.
But for caching reasons you should consider localizing dates and times on the client side.

Rails: Take an unformatted datetime and assign it a time zone w/o changing the time?

I'm importing an object from an API with a datetime that looks like this:
"2017-06-28 09:00:00"
This time is in the user's time zone, which is known in my application. (i.e. Pacific Time (US & Canada))
Datetimes are stored in my database as datetime format in UTC. When we display dates on the front-end, we account for the user's time zone (ie datetime.in_time_zone(user_time_zone)).
How do I save the datetime in my database correctly?
You should be able to append your apps timezone to the end of the datetime string.
time = "2017-06-28 09:00:00"
time += Time.zone.name
Parsing that will give you the time in Pacific Time (US & Canada). Or use ActiveSupport.
time_pacific = DateTime.parse(time)
### ActiveSupport version ###
time_pacific = ActiveSupport::TimeZone.new(Time.zone.name).parse("2017-06-28 09:00:00")
You can then call #utc on that to get the correct UTC time from your original string.
time_utc = time_pacific.utc

Timezones in Rails 5 when using beginnig_of_month

My Rails 5 app is set to BRT (Brazilian timezone) and my Postgres database to UTC. I never had to worry about that because Rails always calculated the correct time when reading from or writing to the database. So for example when I had an input field with time = 15:00 it would write 18:00 to the database and when reading from the database it would return 15:00 again. Perfect!
But now I want to write the beginning of the month to the database:
Time.now.beginning_of_month which is 2017-04-01 00:00:00
Payment.create(
:time => Time.now.beginning_of_month
)
Now it writes exactly this (in BRT) to the database without converting to UTC. When I read this from the database later it converts it to BRT 2017-03-31 21:00:00 which is wrong.
Of course I could convert the time to UTC before saving it to the database. But I find it strange that Rails always took care of converting and in this case it does not.
I hope the problem became clear.
Any ideas?
I found a very good article about this subject:
https://www.varvet.com/blog/working-with-time-zones-in-ruby-on-rails/
Basically what I had to to is change Time.now to Time.current as Time.now ignores the timezone settings.

Rails timestamp different than mysql timestamp

My rails application has a Photo model which has a DATETIME column called taken_at.
I'm trying to understand why I get a different timestamp (num of secs since epoch) using the following methods:
Photo.find(3095).taken_at.to_i # => 1307292495
Photo.select("id, UNIX_TIMESTAMP(taken_at) as timestamp").where(:id => 3095).first['timestamp'] # => 1307317695
Photo.find(3095).taken_at.strftime('%s') # => "1307267295"
I'm using MySQL as the database and I'm using rails 4.1.7
thanks!
So the reason that using UNIX_TIMESTAMP(taken_at) in MYSQL gives a different result is because MySQL assumes that taken_at is a date stored in the server's time zone and converts it to an internal value in UTC before making the timestamp calculation. But taken_at isn't a date stored in the server's time zone, it is a date stored in UTC because ActiveRecord stores all datetimes as UTC in the database and then converts them back to the local time zone when you read the record back from the database.
references:
http://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html#function_utc-timestamp

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.

Resources