My server is in US, rails default timezone is set to 'UTC', a user from India submits the form,Will rails convert that user's time zone from India to UTC and save it in created_at column or it will save the UTC current time?
It will save the current time in UTC. Created_at and updated_at are Active Records internal timestamp columns, and as such they are never user input.
Also, basic security protocol dictates that you should never use the client's time settings, always the servers.
Rails will do one thing though - it will use the webserver's current time in UTC and store it in the database instead of the database servers current time.
By default, times are stored in UTC + offset format. When you specify the default timezone as lets say "Mumbai" it will return the datetime objects converted for that timezone.
You can also do:
Time.zone.parse(#post.created_at.zone)
Related
I have weird situation with my PostgreSQL db date value.
On my web site I have calendar for selecting a date and when I select some future date like "2018-09-23" in PostgreSQL table column it is saved as "2018-09-22 22:00:00"?
Obviously I am missing something. On web site all the time it shows okay time "2018-09-23" but at the table it is minus one day as you see above. Why?
Rails stores DateTime fields in UTC, but without marking their time zone as UTC. This corresponds to the timestamp without time zone type in postgres. So if your time zone is +2, it'll store the time as UTC (+0).
In Rails, Time.zone will return the current local timezone (you can add logic to change this by user, for example). When persisting a datetime, Rails will automatically convert the current Time.zone to UTC. However, it doesn't use the Postgres type that actually includes the time zone data, so it relies on convention to convert back and forth to the user's time zone.
If you really only care about the date, use the date type in your migration instead of Timestamp or DateTime.
Times and dates have a lot of subtle quirks and the "right" behavior depends on your use case. In some applications, you need to deal with "local" time when considering date transitions, and sometimes you need to finesse your application or database logic to think in terms of local time and sometimes you care about UTC time.
I have to store an "event time" that could be in any timezone. By default rails stores these in the DB as UTC and strips off our custom timezone. When we read the attribute back it is converted to our application's timezone - we lose the original timezone information.
We're working around this by storing the timestamp (as UTC) and an offset (an integer number of seconds) which is fine, but I'd really love to be able to store this as just one column and have rails use that rather than converting to UTC on write and to the application's timezone on read.
Is having rails store the timestamp in non-UTC just for this one field just not possible?
I have table which have a datetime field named date. When doing a POST in order to insert a new row, the date sent from the client (browser) looks like 2015-11-20T14:30:00+10:00 which is actually a correct date and timezone.
However, inside Postgres this date has been inserted as 2015-11-20 04:30:00.000000, which as you can see, is not at all the same as above. I know the problem is related to the timezone. But I cannot seems to figure out a fix.
For information, I have configured my app timezone :
class Application < Rails::Application
config.time_zone = 'Brisbane'
end
Ideas?
2015-11-20T14:30:00+10:00 means that the local time of 14:30 is 10 hours ahead of UTC. Your database field reflects the correct UTC value of 04:30. This is often the desired behavior, especially if the value represent a timestamp - the date and time something occured (past tense).
In PostgreSQL, there are two different types of timestamp fields (reference)
The TIMESTAMP WITH TIME ZONE field accepts an input that contains a time zone offset. It then converts the value to UTC for storage. On retrieval, it uses the session's timezone setting.
The TIMESTAMP, or TIMESTAMP WITHOUT TIME ZONE simply stores the date and time given, ignoring any offset, and not converting to UTC.
Most of the time, you should indeed use TIMESTAMP WITH TIME ZONE. You should only use TIMESTAMP WITHOUT TIME ZONE if you need to retain the local date and time value, such as in scheduling of future events and calculation of business hours. And for those scenarios, it often makes more sense to split date and time into separate DATE and TIME fields.
One last thing - if you can avoid it, avoid using Rails time zones and use standard tzdb zones. "Australia/Brisbane" is the full tzdb identifier equivalent to the Rails "Brisbane" time zone. Refer to the section on Rails time zones at the bottom of the timezone tag wiki.
I found this gem to be incredibly useful and easy for correctly setting the time https://github.com/kbaum/browser-timezone-rails
When i save a DateTime schedule_time to the DB, it saves according to my local time, but the timestamps (created_at) are saved apparently in UTC (7 hours ahead of my pacific time)
So if i submit the form setting my schedule_time for right now it will be 7 hours different than my created_at.
i need to show many users their times in their own selected zone, and i also need to compare times against each other, so i want all db entries to be in the same zone. Testing on my machine, my user has his zone saved as Pacific (-7:00), but its saving schedule_time in local time, not really UTC, so when i try to display the time back like this:
#item.schedule_time.in_time_zone(#user.time_zone)
it actually takes the stored datetime and subtracts seven hours from it giving me 7 hours before i wanted. i think the best thing is to just store all the datetimes in a uniform way so i can compare them easily.
changing this value config.time_zone = 'UTC' does nothing to change the stored format of my datetime. it stores in my local time regardless, while storing the timepstamps in real UTC.
ive also tried to reformat the datetime before storing it, with in_time_zone(#user.time_zone) but it had no effect on the stored time.
if i can just get schedule_time stored in UTC just like my timestamps are stored i could make this work! any ideas?
If you want to store schedule_time converted to UTC before storing it in the database, you can include a before_save callback in your Item model to convert it as follows:
before_save { |item| item.schedule_time = item.schedule_time.utc }
sorry i was totally on the wrong track.
the issue was with the jquery date picker i was using (will_pickdate). it returns a date and time but with a +0000 time zone offset. by default, the picker autofills with the current local time, but when i submitted that, rails basically thought it was receiving a time in UTC and added it as my local time but with +0000.
in order to store the date properly i have to keep the time and date from the picker intact, but just shift the +0000 part to something appropriate:
my_time.change(offset: user_time_zone_offset)
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.