Created
October 31, 2014 12:32
-
-
Save conf/f3d18db8370961c8540f to your computer and use it in GitHub Desktop.
Monkey patch ActiveSupport::TimeZone to fix TZInfo::AmbiguousTime errors
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# put this file in config/initializers/monkey_patches.rb | |
require 'monkey_patches/active_support/time_zone' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# put this in lib/monkey_patches/active_support/time_zone.rb | |
module MonkeyPatches | |
module ActiveSupport | |
module TimeZone | |
extend ::ActiveSupport::Concern | |
included do | |
alias_method_chain :period_for_local, :ambiguous_handling | |
end | |
# This monkey patch fixes exceptions like this one: | |
# TZInfo::AmbiguousTime: 2014-10-26 01:00:12 UTC is an ambiguous local time. | |
# They happen to appear when code like `3.days.ago` or `Time.zone.parse('some ambiguous date here')` is used, | |
# i.e. when some local time point can be translated into more than 1 points of time in UTC time, like it's | |
# happened in Europe/Moscow on October 26, 2014 when time from 01:00:00 till 01:59:59 went twice: | |
# 01:00:00 MSK +04:00 -> 01:59:59 MSK +04:00 | |
# 01:59:59 MSK +04:00 -> 01:00:00 MSK +03:00 | |
# 01:00:00 MSK +03:00 -> 02:00:00 MSK +04:00 | |
# This change is permanent, so no daylight saving time (DST) is involved here | |
# See https://github.com/tzinfo/tzinfo/issues/32 for discussion | |
# | |
# Most of the time TZInfo resolves ambiguous dates by itself, but when it can't we have to choose it manually | |
# via supplied block, so take the earlier date by default | |
def period_for_local_with_ambiguous_handling(time, dst=true) | |
tzinfo.period_for_local(time, dst) { |results| results.first } | |
end | |
end | |
end | |
end | |
ActiveSupport::TimeZone.send :include, MonkeyPatches::ActiveSupport::TimeZone |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# put this file in spec/lib/monkey_patches/active_support/time_zone_spec.rb | |
require 'spec_helper' | |
require 'timecop' | |
describe MonkeyPatches::ActiveSupport::TimeZone do | |
describe 'ambigious time bug' do | |
# I could reproduce this bug only on Rails 3.x | |
it 'n.days.ago should not throw exception' do | |
Timecop.travel(Time.zone.parse('27.10.2014 1:30:00 MSK +03:00')) do | |
expect { 1.day.ago }.not_to raise_error | |
end | |
end | |
it 'Time.zone.parse should not throw exception' do | |
expect { Time.zone.parse('26.10.2014 1:30:00') }.not_to raise_error | |
end | |
end | |
end |
I am using this patch only while running specs (since only my specs are affected) so I'll put it in spec/support
and require it in my rails_helper.rb
. I hope it will help me get rid of those flaky tests, thanks
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hi. In rails 5 there is this thing: