Rails: saving record from console with Timezone - ruby-on-rails

I created a new object and saved the same through the console. I noticed that created_at and updated_at columns were in GMT format but when I do a Time.now in my console I get the time in my time zone. How can save my records from the console with my local time?

Rahul, Rails correctly goes out of its way to store dates in UTC (like GMT) format. I strongly advise against undoing this.
Rails (and ruby) provides Time.zone, Time.local and other methods that help you display the values in the correct local time. Your local time is determined by the settings of your system, but your local time isn't necessarily the same as that of other people using the system. Once you put this on a web server in the wild, people may be in different time zones. You can tell Rails which time zone to use by default in application.rb in this section
# 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 = 'Eastern Time (US & Canada)'
This might work OK for cases where most of your users are in the same timezone, but if you want users to be able to see date/times in their timezone, you'll probably want to store their zone in the User record. There's a time_zone_select helper to make it easy to capture that info.

Related

Managing multiple users time zones in ruby on rails

I want to save an event in a default time zone i.e. Whenever an user submits an event it will get convert to the default time zone and will be save in the database.
Whenever user requests for an event, the system will find that users time zone and convert the date (from the default format) in that user time zone and display it to the user.
I'm having difficult time where to start from i saw many notes and documents but couldn't figure it out the complete process of doing it.
I saw this code but couldn't understand how to use it :
before_filter :set_time_zone
def set_time_zone
Time.zone = current_user.time_zone if current_user
end
The default time zone in the database is UTC.
There are 2 ways you can do it:
Allow their user to store their time zone in the database
Grab their time zone from their IP
For option 1, Rails has very good support for time zones. The #all method will allow you to create a dropdown for them to choose from. Then save it in the database with the user record.
Option 2 is less work for the user, but is also less accurate. There are a few services that convert IP's to Time Zones.
To display the time in a given time zone, use Time#in_time_zone or you can set the Time.zone as above and it should display properly.

How to deal with UTC times and Rails/ActiveRecord

I'm using Rails 3.2.8. When I generate a scaffold with a time field or datetime field. The HTML form field gets pre-populated with the current date/time in UTC. Great that it's pre-populated with the current date/time, but because it's in UTC, we have to change the time back 7 hours every time (which will sometimes require setting the day back 1 also, possibly month and year too). And then it seems the UTC time gets stored in the database, so I'll have issues displaying/editing it as well if I recorded it in our local time.
I looked at the Ruby documentation for the form helpers to deal with local time better, but I don't see anything relevant.
What's the best way to deal with editing and displaying dates and times in Rails?
UPDATE: To clarify, I like the idea that UTC time is stored in the database. I just want the time_select and datetime_select form helpers to edit the times in the user's local timezone. And, of course, I want to easily display the time in the user's local timezone.
You have to set the time zone to display on a per-user basis somewhere in a before/around_filter. This has to be done like:
Time.zone = "Kyiv"
An example can be found in its API: http://api.rubyonrails.org/classes/Time.html#method-c-zone-3D.
Run the rake time:zones:all to see all of them.
All the conversions has to be handled for you behind the scene.
This has helped me in the past. You can do things like:
Time.now.in_time_zone("Central Time (US & Canada)")
See Rails: convert UTC DateTime to another time zone

Rails 3.1 time zone confused?

Here is my current situation:
I have a user class that has an attribute time zone.
When the user creates a Lecture with start_time (3pm) and end_time (5pm), I want to ensure that in the database the start_time and end_time are actually 3pm and 5pm, in the user's time zone.
In my application controller I'm doing the following:
def set_timezone
if current_user
Time.zone = current_user.time_zone or "Eastern Time (US & Canada)"
end
end
When the above lecture is saved to the database it seems to add 4 hours. Is it converting it back to UTC? The odd thing is that when I display the time in the view it is correct (I'm guessing it's converted from the UTC time back to the EST time).
I want it so that that if a user selects 4pm it is saved in the database as 4pm AND when I display that time in the view it is 4pm. What am I currently doing wrong?
EDIT: it appears that rails also converts all times to UTC when storing them in the database. Which is ok until I do a query that involves time (I'll have to manually convert it to UTC).
MySQL also has a time zone.
Notably (emphasis mine):
The current session time zone setting affects display and storage of time values that are zone-sensitive. This includes the values displayed by functions such as NOW() or CURTIME(), and values stored in and retrieved from TIMESTAMP columns. Values for TIMESTAMP columns are converted from the current time zone to UTC for storage, and from UTC to the current time zone for retrieval.
Whether or not it's worth doing anything about it... not sure. I'm skeptical.

Rails/Activerecord database field timezone

I have a database that is written to by a non-rails application and read from by a rails application. There is a datetime field in the database and the data stored in this field is stored in Eastern Time. In my rails app, I understand I can set the application's timezone in my environment.rb file by doing config.time_zone = 'Eastern Time (US & Canada)'. However, rails assumes the data stored in the database is stored in UTC and converts from config.time_zone to UTC as it pulls information in and out of the database.
Is there a way to tell rails the data in this particular field, or even all my datetime fields, is Eastern Time and not UTC?
On Rails 3.0.5 in application.rb, this works:
config.time_zone = 'Central Time (US & Canada)'
config.active_record.default_timezone = :local
config.active_record.default_timezone - Tells ActiveRecord to interpret database times as being in the specified time zone, and to use this timezone for working with the created_at & updated_at attributes.
my first suggestion is to fix the other application. The other application should be storing a UTC offset with the date. If you try working around a problem, you are just going to create more. For instance, what happens when daylight savings time goes, then are the offsets going to change?
That being said and having no other choice - I would do something along these lines, for a field created_at:
def created_at_in_eastern
DateTime.parse(self.created_at.strftime("%D %T EST")) if self.created_at
end
or you can use EDT depending on how the data is saved, just read the disclaimer at the top - this is a hack!

When is it appropriate to use Time#utc in Rails 2.1?

I am working on a Rails application that needs to handle dates and times in users' time zones. We have recently migrated it to Rails 2.1 and added time zone support, but there are numerous situations in which we use Time#utc and then compare against that time. Wouldn't that be the same as comparing against the original Time object?
When is it appropriate to use Time#utc in Rails 2.1? When is it inappropriate?
If you've set:
config.time_zone = 'UTC'
In your environment.rb (it's there by default), then times will automagically get converted into UTC when ActiveRecord stores them.
Then if you set Time.zone (in a before_filter on application.rb is the usual place) to the user's Time Zone, all the times will be automagically converted into the user's timezone from the utc storage.
Just be careful with Time.now.
Also see:
http://mad.ly/2008/04/09/rails-21-time-zone-support-an-overview/
http://errtheblog.com/posts/49-a-zoned-defense - you can use the JS here to detect zones
Hope that helps.
If your application has users in multiple time zones, you should always store your times in UTC (any timezone would work, but you should stick with the most common convention).
Let the user input in local time, but convert to UTC to store (and compare, and manipulate). Then, convert back from UTC to display in each users' local time zone.

Resources