diff --git a/activesupport/lib/active_support/core_ext/string/conversions.rb b/activesupport/lib/active_support/core_ext/string/conversions.rb index 541f969faa2d7..cd7a4f4f95711 100644 --- a/activesupport/lib/active_support/core_ext/string/conversions.rb +++ b/activesupport/lib/active_support/core_ext/string/conversions.rb @@ -2,23 +2,35 @@ require 'active_support/core_ext/time/calculations' class String - # Form can be either :utc (default) or :local. + # Attempts to converts itself to a Time object and + # returns nil if it can't. + # form can be either :utc (default) or :local. def to_time(form = :utc) return nil if self.blank? - d = ::Date._parse(self, false).values_at(:year, :mon, :mday, :hour, :min, :sec, :sec_fraction, :offset).map { |arg| arg || 0 } - d[6] *= 1000000 - ::Time.send("#{form}_time", *d[0..6]) - d[7] + parts = ::Date._parse(self, false).values_at(:year, :mon, :mday, :hour, :min, :sec, :sec_fraction, :offset) + return nil unless parts.any? + parts.map! {|part| part || 0 } + parts[6] *= 1000000 + ::Time.send("#{form}_time", *parts[0..6]) - parts[7] end + # Attempts to converts itself to a Date object and + # returns nil if it can't. def to_date return nil if self.blank? - ::Date.new(*::Date._parse(self, false).values_at(:year, :mon, :mday)) + parts = ::Date._parse(self, false).values_at(:year, :mon, :mday) + return nil unless parts.any? + ::Date.new(*parts) end + # Attempts to converts itself to a DateTime object and + # returns nil if it can't. def to_datetime return nil if self.blank? - d = ::Date._parse(self, false).values_at(:year, :mon, :mday, :hour, :min, :sec, :zone, :sec_fraction).map { |arg| arg || 0 } - d[5] += d.pop - ::DateTime.civil(*d) + parts = ::Date._parse(self, false).values_at(:year, :mon, :mday, :hour, :min, :sec, :zone, :sec_fraction) + return nil unless parts.any? + parts.map! {|part| part || 0 } + parts[5] += parts.pop + ::DateTime.civil(*parts) end end diff --git a/activesupport/test/core_ext/string_ext_test.rb b/activesupport/test/core_ext/string_ext_test.rb index 6c2828b74e11a..799b40aa1f22a 100644 --- a/activesupport/test/core_ext/string_ext_test.rb +++ b/activesupport/test/core_ext/string_ext_test.rb @@ -168,6 +168,7 @@ def test_string_to_time assert_equal DateTime.civil(2039, 2, 27, 23, 50), "2039-02-27 23:50".to_time assert_equal Time.local_time(2039, 2, 27, 23, 50), "2039-02-27 23:50".to_time(:local) assert_equal Time.utc(2011, 2, 27, 23, 50), "2011-02-27 22:50 -0100".to_time + assert_nil "foo".to_time assert_nil "".to_time end @@ -176,11 +177,13 @@ def test_string_to_datetime assert_equal 0, "2039-02-27 23:50".to_datetime.offset # use UTC offset assert_equal ::Date::ITALY, "2039-02-27 23:50".to_datetime.start # use Ruby's default start value assert_equal DateTime.civil(2039, 2, 27, 23, 50, 19 + Rational(275038, 1000000), "-04:00"), "2039-02-27T23:50:19.275038-04:00".to_datetime + assert_nil "foo".to_datetime assert_nil "".to_datetime end def test_string_to_date assert_equal Date.new(2005, 2, 27), "2005-02-27".to_date + assert_nil "foo".to_date assert_nil "".to_date end