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

Comments

Projects
None yet
@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

This comment has been minimized.

Show comment
Hide comment
@guiocavalcanti

guiocavalcanti Sep 27, 2011

Contributor

What rails version are you using?

Contributor

guiocavalcanti commented Sep 27, 2011

What rails version are you using?

@thiagodiniz

This comment has been minimized.

Show comment
Hide comment
@thiagodiniz

thiagodiniz Sep 27, 2011

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

thiagodiniz commented Sep 27, 2011

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

@rodrigoalvesvieira

This comment has been minimized.

Show comment
Hide comment
@rodrigoalvesvieira

rodrigoalvesvieira Sep 27, 2011

This also happened with me when using Rails 3.1.0.

rodrigoalvesvieira commented Sep 27, 2011

This also happened with me when using Rails 3.1.0.

@pixeltrix

This comment has been minimized.

Show comment
Hide comment
@pixeltrix

pixeltrix Sep 27, 2011

Member

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.

Member

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

This comment has been minimized.

Show comment
Hide comment
@thiagodiniz

thiagodiniz Sep 27, 2011

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

thiagodiniz commented Sep 27, 2011

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

@pixeltrix

This comment has been minimized.

Show comment
Hide comment
@pixeltrix

pixeltrix Sep 27, 2011

Member

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.

Member

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

This comment has been minimized.

Show comment
Hide comment
@jeremyf

jeremyf Apr 28, 2012

Contributor

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

(@jeremyf)

Contributor

jeremyf commented Apr 28, 2012

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

(@jeremyf)

@pixeltrix

This comment has been minimized.

Show comment
Hide comment
@pixeltrix

pixeltrix Apr 28, 2012

Member

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.

Member

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

This comment has been minimized.

Show comment
Hide comment
@thiagodiniz

thiagodiniz 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!

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

This comment has been minimized.

Show comment
Hide comment
@jeremyf

jeremyf Apr 29, 2012

Contributor

@thiagodiniz can you close the ticket?

Contributor

jeremyf commented Apr 29, 2012

@thiagodiniz can you close the ticket?

@pixeltrix

This comment has been minimized.

Show comment
Hide comment
@pixeltrix

pixeltrix Apr 29, 2012

Member

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.

Member

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

This comment has been minimized.

Show comment
Hide comment
@dreki

dreki 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.

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

This comment has been minimized.

Show comment
Hide comment
@JasonBenn

JasonBenn Jul 18, 2013

Is this still an issue?

JasonBenn commented Jul 18, 2013

Is this still an issue?

@pixeltrix

This comment has been minimized.

Show comment
Hide comment
@pixeltrix

pixeltrix Jul 19, 2013

Member

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

Member

pixeltrix commented Jul 19, 2013

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

@unorthodoxgeek

This comment has been minimized.

Show comment
Hide comment
@unorthodoxgeek

unorthodoxgeek 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.

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

This comment has been minimized.

Show comment
Hide comment
@jsuwo

jsuwo Jan 30, 2014

Bug still exists in Rails 4.0.2.

jsuwo commented Jan 30, 2014

Bug still exists in Rails 4.0.2.

@pixeltrix

This comment has been minimized.

Show comment
Hide comment
@pixeltrix

pixeltrix Jan 30, 2014

Member

@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.

Member

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

This comment has been minimized.

Show comment
Hide comment
@jsuwo

jsuwo 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.

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

This comment has been minimized.

Show comment
Hide comment
@rafaelfranca

rafaelfranca May 1, 2014

Member

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.

Member

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

This comment has been minimized.

Show comment
Hide comment
@sgrif

sgrif Jun 14, 2014

Member

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.

Member

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

This comment has been minimized.

Show comment
Hide comment
@sgrif

sgrif Jun 14, 2014

Member

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

Member

sgrif commented Jun 14, 2014

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

@sgrif

This comment has been minimized.

Show comment
Hide comment
@sgrif

sgrif Jun 14, 2014

Member

#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.)

Member

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

This comment has been minimized.

Show comment
Hide comment
@thiagodiniz

thiagodiniz Jun 14, 2014

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

thiagodiniz commented Jun 14, 2014

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

@sobrinho

This comment has been minimized.

Show comment
Hide comment
@sobrinho

sobrinho Jun 14, 2014

Contributor

Thanks @sgrif!

Contributor

sobrinho commented Jun 14, 2014

Thanks @sgrif!

@pixeltrix

This comment has been minimized.

Show comment
Hide comment
@pixeltrix

pixeltrix Jun 14, 2014

Member

@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?

Member

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

This comment has been minimized.

Show comment
Hide comment
@sgrif

sgrif Jun 14, 2014

Member

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.

Member

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

This comment has been minimized.

Show comment
Hide comment
@sgrif

sgrif Jun 15, 2014

Member

@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.

Member

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

This comment has been minimized.

Show comment
Hide comment
@simonask

simonask 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.

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

This comment has been minimized.

Show comment
Hide comment
@sgrif

sgrif Aug 22, 2014

Member

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

Member

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

This comment has been minimized.

Show comment
Hide comment
@rails-bot

rails-bot 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.

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

This comment has been minimized.

Show comment
Hide comment
@zouis

zouis 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 ?

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

This comment has been minimized.

Show comment
Hide comment
@MrOvitch

MrOvitch 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)

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 bot removed the stale label Sep 11, 2017

@paulomcnally

This comment has been minimized.

Show comment
Hide comment
@paulomcnally

paulomcnally 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.

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