Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Time is created in UTC with local time #3145

Closed
thiagodiniz opened this issue Sep 27, 2011 · 33 comments
Closed

Time is created in UTC with local time #3145

thiagodiniz opened this issue Sep 27, 2011 · 33 comments
Assignees
Labels
Milestone

Comments

@thiagodiniz
Copy link

@thiagodiniz thiagodiniz commented Sep 27, 2011

When a Model is created using the mass assignment, and the model has a time attribute.

The Time attribute is created in local time but with UTC time zone even with config.time_zone properly setted.

I was studying this wrong behavior and guess that the error is here:

https://github.com/rails/rails/blob/master/activerecord/lib/active_record/attribute_methods/time_zone_conversion.rb#L62

As you can see, in the line 62 it only consider :datetime and :timestamp. it does not consider :time to be timezone aware.

@guiocavalcanti
Copy link
Contributor

@guiocavalcanti guiocavalcanti commented Sep 27, 2011

What rails version are you using?

@thiagodiniz
Copy link
Author

@thiagodiniz thiagodiniz commented Sep 27, 2011

I have tried from rails 3.0.7 til 3.0.10. all the same bug.

@rodrigoalvesvieira
Copy link

@rodrigoalvesvieira rodrigoalvesvieira commented Sep 27, 2011

This also happened with me when using Rails 3.1.0.

@pixeltrix
Copy link
Member

@pixeltrix pixeltrix commented Sep 27, 2011

Can a time be timezone aware without a date? What about daylight savings handling? For example a local time in Europe/London today is one hour ahead of UTC but in a month’s time it will be equivalent to UTC.

@thiagodiniz
Copy link
Author

@thiagodiniz thiagodiniz commented Sep 27, 2011

Pixeltrix, that's why Time in ruby as a date. Have you understood my problem?

@pixeltrix
Copy link
Member

@pixeltrix pixeltrix commented Sep 27, 2011

The problem with treating a time column as timezone aware is that the conversion to local time will be different depending on what day of the year you access it. For example if I save a local time in Europe/London today it will take a hour off when saving it to the database in UTC format. When I come to read that time in a month then the local time generated from the UTC time in the database will be different to the one that was saved.

@jeremyf
Copy link
Contributor

@jeremyf jeremyf commented Apr 28, 2012

@thiagodiniz Is this still a problem in Rails 3.2.x?

(@jeremyf)

@pixeltrix
Copy link
Member

@pixeltrix pixeltrix commented Apr 28, 2012

After investigating this I'm leaning towards closing this because it's pretty much an intractable problem. It turns out that time columns are all given the same date (2000-01-01 to be precise). This can cause an issue if you use Time.current and have set a time zone for your app - for example if I create a record using Time.current today then the time saved is one hour behind local time but even if it's converted to the timezone on reading the record it won't help as the date set is not in BST (British Summer Time) and so will be one hour out.

Just using the current date wouldn't help as it would return a different time depending on what day of the year you read the record. One possible solution is to write time columns out as local time and not as UTC and read them in as local time. At least this way you'd end up with the same time on every day of the year.

@thiagodiniz
Copy link
Author

@thiagodiniz thiagodiniz commented Apr 29, 2012

@jeremyf, i haven't tested yet. Thanks for the remider.
I have dropped the use of time.

@pixeltrix thanks for taking a look in this case!

@jeremyf
Copy link
Contributor

@jeremyf jeremyf commented Apr 29, 2012

@thiagodiniz can you close the ticket?

@pixeltrix
Copy link
Member

@pixeltrix pixeltrix commented Apr 29, 2012

Don't close it just yet as I need to discuss with either @tenderlove or @jonleighton whether we should use Time.change to switch the date to 01/01/2000 before writing the time to the database. At least that way it would be consistent.

@dreki
Copy link

@dreki dreki commented Jun 20, 2012

For anyone stumbling across this, here's a way I created to address this in your models:

https://gist.github.com/2961926

Put this in lib/. Then do this

class MyModel < ActiveRecord::Base
  include DstHelper

  applies_dst :from => :date, :to => :time

  # ...
end

Now, when you access my_model.time, you'll get what you expect for the given date.

@JasonBenn
Copy link

@JasonBenn JasonBenn commented Jul 18, 2013

Is this still an issue?

@pixeltrix
Copy link
Member

@pixeltrix pixeltrix commented Jul 19, 2013

@JasonBenn I think so - I'll try and take a look at it this weekend

@unorthodoxgeek
Copy link

@unorthodoxgeek unorthodoxgeek commented Aug 30, 2013

I tried to replicate this in a test (see PR) and it all seems to work like expected, the time is saved as utc, but correctly so...

Albeit, issue #6816 is actually a better description of the unexpected behavior - the time is read as utc, and not converted to local time on the read. That might be something worth looking into.

@jsuwo
Copy link

@jsuwo jsuwo commented Jan 30, 2014

Bug still exists in Rails 4.0.2.

@pixeltrix
Copy link
Member

@pixeltrix pixeltrix commented Jan 30, 2014

@jsuwo I'm aware that it still exists but unfortunately it would impact on too many things this late in the release cycle so it's scheduled for fixing in 4.2.

@jsuwo
Copy link

@jsuwo jsuwo commented Jan 30, 2014

@pixeltrix Yep, I just wanted to mention it since I saw a number of posts asking if this was still an issue. Thanks.

@thiagodiniz thiagodiniz added the stale label May 1, 2014
@rafaelfranca
Copy link
Member

@rafaelfranca rafaelfranca commented May 1, 2014

This issue has been automatically marked as stale because it has not been commented on for at least
three months.

The resources of the Rails team are limited, and so we are asking for your help.

If you can still reproduce this error on the 4-1-stable, 4-0-stable branches or on master,
please reply with all of the information you have about it in order to keep the issue open.

Thank you for all your contributions.

@sgrif
Copy link
Contributor

@sgrif sgrif commented Jun 14, 2014

I was unable to reproduce this issue using the following gist, on any of the currently supporting branches. https://gist.github.com/sgrif/0af0158e1875387956a7. Since this issue is also marked as stale, I'm going to close this, since it appears to be resolved. If this issue still exists for you, please open a new issue.

@sgrif sgrif closed this Jun 14, 2014
@sgrif
Copy link
Contributor

@sgrif sgrif commented Jun 14, 2014

Apologies, I mistakenly read this as datetime, rather than time. This issue is still present.

@sgrif
Copy link
Contributor

@sgrif sgrif commented Jun 14, 2014

#15726 fixes this for 4.2. It's a significantly more difficult change to make without the refactoring work I've done in master, so I'm not sure that we can back port it to 4.1 or 4.0, but I will spend some time looking at it. (Any back port would add a configuration option to allow this behavior on 4.1, but the default would need to remain the same.)

@thiagodiniz
Copy link
Author

@thiagodiniz thiagodiniz commented Jun 14, 2014

@sgrif, thank you for the time spent solving this issue.

@sobrinho
Copy link
Contributor

@sobrinho sobrinho commented Jun 14, 2014

Thanks @sgrif!

@pixeltrix
Copy link
Member

@pixeltrix pixeltrix commented Jun 14, 2014

@sgrif does #15726 address the problem that if you use Time.current then you'll get different times depending on whether DST is in affect or not? It doesn't seem like it but does the other refactoring you've done affect it?

@sgrif
Copy link
Contributor

@sgrif sgrif commented Jun 14, 2014

Not sure if we can do anything about Time.current. Everything will convert properly going into the database, but we lose the date (and therefore DST) info coming back out. I'll spend some time looking at this case tomorrow and see if I can at least make sure the behavior is documented.

@sgrif
Copy link
Contributor

@sgrif sgrif commented Jun 15, 2014

@pixeltrix I've updated to handle the Time.current case. I opted to go with Time#change here, in order to keep our contract consistent in regards to attribute assignment.

model.attr = value

# This is not guaranteed
model.attr == value

# These are guaranteed
model.attr_before_type_cast == value
model.save
model.attr == model.reload.attr

Since the date will be lost when round tripping, and we assume the date is 2000-01-01 coming out, we should make enforce that the same is true going in.

@rafaelfranca rafaelfranca modified the milestones: 4.2.0, 5.0.0 Aug 18, 2014
@simonask
Copy link

@simonask simonask commented Aug 22, 2014

Is there a suitable workaround for this issue? I'm seeing the behaviour that if ActiveRecord::Base.default_timezone is set to something other than :utc, timestamps get saved in the database in the local time, but are read as if they were UTC. Setting it to :utc means all times get displayed in UTC instead of our users' local time.

@sgrif
Copy link
Contributor

@sgrif sgrif commented Aug 22, 2014

@simonask That sounds like an unrelated issue, please open a bug report with a reproducible case demonstrating the behavior.

@rails-bot rails-bot added the stale label Jan 2, 2015
@rails-bot
Copy link

@rails-bot rails-bot commented Jan 2, 2015

This issue has been automatically marked as stale because it has not been commented on for at least
three months.

The resources of the Rails team are limited, and so we are asking for your help.

If you can still reproduce this error on the 4-1-stable, 4-0-stable branches or on master,
please reply with all of the information you have about it in order to keep the issue open.

Thank you for all your contributions.

@zouis
Copy link

@zouis zouis commented Jul 18, 2015

That's not working for me. I updated to 4.2, set config.time_zone = 'Europe/Paris' but still have UTC time 2000-01-01 18:00:00 UTC
Am I missing something ?

@rafaelfranca rafaelfranca modified the milestones: 5.0.0 [temp], 5.0.0 Dec 30, 2015
@MrOvitch
Copy link

@MrOvitch MrOvitch commented Sep 11, 2017

2 years later, we have this problem (only in local/staging env but not in production..)
we have an old app that uses :

  • ruby '2.1.5'
  • gem 'rails', '3.2.14'

applications.rb have
config.time_zone = 'Europe/Paris'

without config.active_record.default_timezone

if we add config.active_record.default_timezone = :local
time are stored utc+2 but displayed utc ...

What can we do in order to fix it for rails 3.2.14 ? (without uppgrading to rails >4.3)

@rails-bot rails-bot removed the stale label Sep 11, 2017
@paulomcnally
Copy link

@paulomcnally paulomcnally commented Dec 31, 2017

Rails 5.1.4

ApplicationController.rb

...
around_action :settings_time_zone
...

...
def settings_time_zone(&block)
    Time.use_zone('America/Managua', &block)
end
...

time_select ignore the timezone.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

You can’t perform that action at this time.