diff options
author | Paul A Jungwirth <pj@illuminatedcomputing.com> | 2015-04-02 05:15:38 +0000 |
---|---|---|
committer | Andrew White <andyw@pixeltrix.co.uk> | 2015-04-22 12:05:07 -0400 |
commit | a5e507fa0b8180c3d97458a9b86c195e9857d8f6 (patch) | |
tree | f365dd94b975e86211821d0e17dae54f62093631 /activesupport | |
parent | 9a034bc3b99cbd219229e88aacf0ec2f53722fe1 (diff) | |
download | rails-a5e507fa0b8180c3d97458a9b86c195e9857d8f6.tar.gz rails-a5e507fa0b8180c3d97458a9b86c195e9857d8f6.tar.bz2 rails-a5e507fa0b8180c3d97458a9b86c195e9857d8f6.zip |
Add ActiveSupport::TimeZone#strptime.
This makes it easier to parse user-inputted times as from a given time zone.
Diffstat (limited to 'activesupport')
-rw-r--r-- | activesupport/CHANGELOG.md | 5 | ||||
-rw-r--r-- | activesupport/lib/active_support/values/time_zone.rb | 20 | ||||
-rw-r--r-- | activesupport/test/time_zone_test.rb | 65 |
3 files changed, 90 insertions, 0 deletions
diff --git a/activesupport/CHANGELOG.md b/activesupport/CHANGELOG.md index a3828f9c73..b1c303e435 100644 --- a/activesupport/CHANGELOG.md +++ b/activesupport/CHANGELOG.md @@ -1,3 +1,8 @@ +* Added `ActiveSupport::TimeZone#strptime` to allow parsing times as if + from a given timezone. + + *Paul A Jungwirth* + * `ActiveSupport::Callbacks#skip_callback` now raises an `ArgumentError` if an unrecognized callback is removed. diff --git a/activesupport/lib/active_support/values/time_zone.rb b/activesupport/lib/active_support/values/time_zone.rb index da39f0d245..ceeb9d3e08 100644 --- a/activesupport/lib/active_support/values/time_zone.rb +++ b/activesupport/lib/active_support/values/time_zone.rb @@ -368,6 +368,26 @@ module ActiveSupport end end + # Parses +str+ according to +spec+ and returns an ActiveSupport::TimeWithZone. + # + # Assumes that +str+ is a time in the time zone +self+, + # unless +spec+ includes an explicit time zone. + # (This is the same behavior as +parse+.) + # In either case, the returned TimeWithZone has the timezone of +self+. + # + # Time.zone = 'Hawaii' # => "Hawaii" + # Time.zone.strptime('1999-12-31 14:00:00', '%Y-%m-%d %H:%M:%S') # => Fri, 31 Dec 1999 14:00:00 HST -10:00 + # + def strptime(str, spec) + case spec + when /(^|[^%](%%)*)%(Z|:{0,3}z)/ + DateTime.strptime(str, spec).in_time_zone(self) + else + t = DateTime.strptime(str, spec) + local(t.year, t.month, t.mday, t.hour, t.min, t.sec, t.usec) + end + end + # Returns an ActiveSupport::TimeWithZone instance representing the current # time in the time zone represented by +self+. # diff --git a/activesupport/test/time_zone_test.rb b/activesupport/test/time_zone_test.rb index 7888b9919b..1293ccfd58 100644 --- a/activesupport/test/time_zone_test.rb +++ b/activesupport/test/time_zone_test.rb @@ -311,6 +311,71 @@ class TimeZoneTest < ActiveSupport::TestCase end end + def test_strptime + zone = ActiveSupport::TimeZone['Eastern Time (US & Canada)'] + twz = zone.strptime('1999-12-31 12:00:00', '%Y-%m-%d %H:%M:%S') + assert_equal Time.utc(1999,12,31,17), twz + assert_equal Time.utc(1999,12,31,12), twz.time + assert_equal Time.utc(1999,12,31,17), twz.utc + assert_equal zone, twz.time_zone + end + + def test_strptime_with_nondefault_time_zone + with_tz_default ActiveSupport::TimeZone['Pacific Time (US & Canada)'] do + zone = ActiveSupport::TimeZone['Eastern Time (US & Canada)'] + twz = zone.strptime('1999-12-31 12:00:00', '%Y-%m-%d %H:%M:%S') + assert_equal Time.utc(1999,12,31,17), twz + assert_equal Time.utc(1999,12,31,12), twz.time + assert_equal Time.utc(1999,12,31,17), twz.utc + assert_equal zone, twz.time_zone + end + end + + def test_strptime_with_explicit_time_zone_as_abbrev + zone = ActiveSupport::TimeZone['Eastern Time (US & Canada)'] + twz = zone.strptime('1999-12-31 12:00:00 PST', '%Y-%m-%d %H:%M:%S %Z') + assert_equal Time.utc(1999,12,31,20), twz + assert_equal Time.utc(1999,12,31,15), twz.time + assert_equal Time.utc(1999,12,31,20), twz.utc + assert_equal zone, twz.time_zone + end + + def test_strptime_with_explicit_time_zone_as_h_offset + zone = ActiveSupport::TimeZone['Eastern Time (US & Canada)'] + twz = zone.strptime('1999-12-31 12:00:00 -08', '%Y-%m-%d %H:%M:%S %:::z') + assert_equal Time.utc(1999,12,31,20), twz + assert_equal Time.utc(1999,12,31,15), twz.time + assert_equal Time.utc(1999,12,31,20), twz.utc + assert_equal zone, twz.time_zone + end + + def test_strptime_with_explicit_time_zone_as_hm_offset + zone = ActiveSupport::TimeZone['Eastern Time (US & Canada)'] + twz = zone.strptime('1999-12-31 12:00:00 -08:00', '%Y-%m-%d %H:%M:%S %:z') + assert_equal Time.utc(1999,12,31,20), twz + assert_equal Time.utc(1999,12,31,15), twz.time + assert_equal Time.utc(1999,12,31,20), twz.utc + assert_equal zone, twz.time_zone + end + + def test_strptime_with_explicit_time_zone_as_hms_offset + zone = ActiveSupport::TimeZone['Eastern Time (US & Canada)'] + twz = zone.strptime('1999-12-31 12:00:00 -08:00:00', '%Y-%m-%d %H:%M:%S %::z') + assert_equal Time.utc(1999,12,31,20), twz + assert_equal Time.utc(1999,12,31,15), twz.time + assert_equal Time.utc(1999,12,31,20), twz.utc + assert_equal zone, twz.time_zone + end + + def test_strptime_with_almost_explicit_time_zone + zone = ActiveSupport::TimeZone['Eastern Time (US & Canada)'] + twz = zone.strptime('1999-12-31 12:00:00 %Z', '%Y-%m-%d %H:%M:%S %%Z') + assert_equal Time.utc(1999,12,31,17), twz + assert_equal Time.utc(1999,12,31,12), twz.time + assert_equal Time.utc(1999,12,31,17), twz.utc + assert_equal zone, twz.time_zone + 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) |