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

Summer time #32550

Closed
YarikST opened this issue Apr 12, 2018 · 6 comments

Comments

@YarikST
Copy link

commented Apr 12, 2018

Steps to reproduce

config
config.time_zone = 'Europe/Kiev'
db - utc

create table - fields time

t = Time.current
r = Table.first
t.field_time = t //15:00 - db save 13:00
Table.where field_time: t - where 12:00

2.4.0 :021 > t = Time.zone.now
 => Thu, 12 Apr 2018 19:59:59 EEST +03:00 
2.4.0 :022 > r.check_at = t
 => Thu, 12 Apr 2018 19:59:59 EEST +03:00 
2.4.0 :023 > r.save
   (0.7ms)  BEGIN
  User Load (1.2ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = $1 LIMIT $2  [["id", 3], ["LIMIT", 1]]
  SQL (1.1ms)  UPDATE "report_histories" SET "check_at" = $1, "updated_at" = $2 WHERE "report_histories"."id" = $3  [["check_at", "17:59:59.049908"], ["updated_at", "2018-04-12 17:00:04.734353"], ["id", 1]]
   (7.9ms)  COMMIT
 => true 
2.4.0 :024 > r.reload
  ReportHistory Load (1.1ms)  SELECT  "report_histories".* FROM "report_histories" WHERE "report_histories"."id" = $1 LIMIT $2  [["id", 1], ["LIMIT", 1]]
 => #<ReportHistory id: 1, user_id: 3, absence_reason_id: nil, check: true, check_at: "2000-01-01 17:59:59", description: "d", reported_head: false, created_at: "2018-04-12 16:55:33", updated_at: "2018-04-12 17:00:04", day_of_week: 0> 
2.4.0 :025 > t
 => Thu, 12 Apr 2018 19:59:59 EEST +03:00 
2.4.0 :026 > ReportHistory.find_by check_at: t
  ReportHistory Load (1.1ms)  SELECT  "report_histories".* FROM "report_histories" WHERE "report_histories"."check_at" = $1 LIMIT $2  [["check_at", "2018-04-12 16:59:59.049908"], ["LIMIT", 1]]
 => nil 
2.4.0 :027 > ReportHistory.find_by check_at: t
  ReportHistory Load (1.2ms)  SELECT  "report_histories".* FROM "report_histories" WHERE "report_histories"."check_at" = $1 LIMIT $2  [["check_at", "2018-04-12 16:59:59.049908"], ["LIMIT", 1]]
 => nil 

where did the hour go ??? preservation and mischief works normally always 15:00 but the search is not right - probably I do something wrong

Expected behavior

where 13:00

Actual behavior

where 12:00

System configuration

5.1.5:

2.4.0:

ways to solve

  • self.skip_time_zone_conversion_for_attributes = [:field_time]
  • config.time_zone = 'UTC'
@pixeltrix

This comment has been minimized.

Copy link
Member

commented Apr 14, 2018

Looks like we should be converting the Ruby Time instance to 2000-01-01 when we're trying to search an SQL TIME column.

@YarikST the issue is that Ruby doesn't have a native class for a time of day without a date component so we try to normalise the date component to 2000-01-01, unfortunately there seems to be a bug where this isn't being done automatically when searching by that column. You should be able to workaround the problem for now by manually converting time value to 2000-01-01 by using change, e.g:

>> t = Time.current
=> Sat, 14 Apr 2018 16:38:49 EEST +03:00
>> t.change(year: 2000, month: 1, day: 1)
=> Sat, 01 Jan 2000 16:38:49 EET +02:00
@pixeltrix

This comment has been minimized.

Copy link
Member

commented Apr 14, 2018

Whilst I fixed an issue in 7c479cb which meant that the leading date component wasn't being stripped from the quoted value there's a logic flaw where we use quoted_date to create the value first and then strip the date component off the string with sub. Unfortunately quoted_date will convert the value to UTC on the date component which may be different to the conversion to UTC on 2000-01-01 - to fix we need to use change in quoted_time to convert it to 2001-01-01 first. The relevant code is here:

def quoted_date(value)
if value.acts_like?(:time)
zone_conversion_method = ActiveRecord::Base.default_timezone == :utc ? :getutc : :getlocal
if value.respond_to?(zone_conversion_method)
value = value.send(zone_conversion_method)
end
end
result = value.to_s(:db)
if value.respond_to?(:usec) && value.usec > 0
"#{result}.#{sprintf("%06d", value.usec)}"
else
result
end
end
def quoted_time(value) # :nodoc:
quoted_date(value).sub(/\A\d\d\d\d-\d\d-\d\d /, "")
end

@SeanPrashad

This comment has been minimized.

Copy link
Contributor

commented Apr 14, 2018

Hi there, I'd love to pick this bug up as my first one for Rails if it's still available!

@pixeltrix

This comment has been minimized.

Copy link
Member

commented Apr 14, 2018

@SeanPrashad I've not done any work on it so 👍 if you want to pick it up

@rails-bot

This comment has been minimized.

Copy link

commented Jul 14, 2018

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 5-2-stable branch 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.

@azbshiri

This comment has been minimized.

Copy link
Contributor

commented Jul 14, 2018

I'll take this. @pixeltrix @rafaelfranca

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
5 participants
You can’t perform that action at this time.