aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordenisovlev <denisovlev@ya.ru>2016-10-20 15:44:22 +0300
committerdenisovlev <denisovlev@ya.ru>2016-10-21 13:19:08 +0300
commit07ffe7a6211b2bac59f385f4a0a67d11e4d42c24 (patch)
treeda000295e5dd71d11eebfea28a35581bf828362e
parentf2c6db41ba56afb1529e4732c59622fc0cf9f3ba (diff)
downloadrails-07ffe7a6211b2bac59f385f4a0a67d11e4d42c24.tar.gz
rails-07ffe7a6211b2bac59f385f4a0a67d11e4d42c24.tar.bz2
rails-07ffe7a6211b2bac59f385f4a0a67d11e4d42c24.zip
Fix `ActiveSupport::TimeZone#strptime` cannot parse timestamps (%Q, %s)
-rw-r--r--activesupport/CHANGELOG.md7
-rw-r--r--activesupport/lib/active_support/values/time_zone.rb26
-rw-r--r--activesupport/test/time_zone_test.rb18
3 files changed, 40 insertions, 11 deletions
diff --git a/activesupport/CHANGELOG.md b/activesupport/CHANGELOG.md
index 91dfc556d3..13d152f4c6 100644
--- a/activesupport/CHANGELOG.md
+++ b/activesupport/CHANGELOG.md
@@ -1,3 +1,10 @@
+* Fix `ActiveSupport::TimeZone#strptime`.
+ Support for timestamps in format of seconds (%s) and milliseconds (%Q).
+
+ Fixes #26840.
+
+ *Lev Denisov*
+
* Fix `DateAndTime::Calculations#copy_time_to`. Copy `nsec` instead of `usec`.
Jumping forward or backward between weeks now preserves nanosecond digits.
diff --git a/activesupport/lib/active_support/values/time_zone.rb b/activesupport/lib/active_support/values/time_zone.rb
index cb97a0e135..a562f33420 100644
--- a/activesupport/lib/active_support/values/time_zone.rb
+++ b/activesupport/lib/active_support/values/time_zone.rb
@@ -450,17 +450,21 @@ module ActiveSupport
raise ArgumentError, "invalid date" if parts.nil?
return if parts.empty?
- time = Time.new(
- parts.fetch(:year, now.year),
- parts.fetch(:mon, now.month),
- parts.fetch(:mday, parts[:year] || parts[:mon] ? 1 : now.day),
- parts.fetch(:hour, 0),
- parts.fetch(:min, 0),
- parts.fetch(:sec, 0) + parts.fetch(:sec_fraction, 0),
- parts.fetch(:offset, 0)
- )
-
- if parts[:offset]
+ if parts[:seconds]
+ time = Time.at(parts[:seconds])
+ else
+ time = Time.new(
+ parts.fetch(:year, now.year),
+ parts.fetch(:mon, now.month),
+ parts.fetch(:mday, parts[:year] || parts[:mon] ? 1 : now.day),
+ parts.fetch(:hour, 0),
+ parts.fetch(:min, 0),
+ parts.fetch(:sec, 0) + parts.fetch(:sec_fraction, 0),
+ parts.fetch(:offset, 0)
+ )
+ end
+
+ if parts[:offset] || parts[:seconds]
TimeWithZone.new(time.utc, self)
else
TimeWithZone.new(nil, self, time)
diff --git a/activesupport/test/time_zone_test.rb b/activesupport/test/time_zone_test.rb
index 76fee1fdd4..bd29584478 100644
--- a/activesupport/test/time_zone_test.rb
+++ b/activesupport/test/time_zone_test.rb
@@ -395,6 +395,24 @@ class TimeZoneTest < ActiveSupport::TestCase
end
end
+ def test_strptime_with_timestamp_seconds
+ with_env_tz "US/Eastern" do
+ zone = ActiveSupport::TimeZone["Eastern Time (US & Canada)"]
+ time_str = "1470272280"
+ time = zone.strptime(time_str, "%s")
+ assert_equal Time.at(1470272280), time
+ end
+ end
+
+ def test_strptime_with_timestamp_milliseconds
+ with_env_tz "US/Eastern" do
+ zone = ActiveSupport::TimeZone["Eastern Time (US & Canada)"]
+ time_str = "1470272280000"
+ time = zone.strptime(time_str, "%Q")
+ assert_equal Time.at(1470272280), time
+ end
+ end
+
def test_utc_offset_lazy_loaded_from_tzinfo_when_not_passed_in_to_initialize
tzinfo = TZInfo::Timezone.get("America/New_York")
zone = ActiveSupport::TimeZone.create(tzinfo.name, nil, tzinfo)