diff options
author | Aaron Patterson <aaron.patterson@gmail.com> | 2010-07-05 16:19:26 -0700 |
---|---|---|
committer | Aaron Patterson <aaron.patterson@gmail.com> | 2010-07-05 16:19:26 -0700 |
commit | 2c2b6e72b18fc6666b218837016b0be9d29c48ce (patch) | |
tree | 10473be8a4b275b837b35df903274ccac9948765 | |
parent | cfa3a13770b4ebb9a5ef4cf168f80f796b84ca3a (diff) | |
download | psych-2c2b6e72b18fc6666b218837016b0be9d29c48ce.zip |
merging changes from ruby
-rw-r--r-- | lib/psych/scalar_scanner.rb | 34 | ||||
-rw-r--r-- | lib/psych/visitors/to_ruby.rb | 3 | ||||
-rw-r--r-- | lib/psych/visitors/yaml_tree.rb | 25 | ||||
-rw-r--r-- | test/psych/test_date_time.rb | 17 | ||||
-rw-r--r-- | test/psych/visitors/test_to_ruby.rb | 12 | ||||
-rw-r--r-- | test/psych/visitors/test_yaml_tree.rb | 2 |
6 files changed, 66 insertions, 27 deletions
diff --git a/lib/psych/scalar_scanner.rb b/lib/psych/scalar_scanner.rb index bee88de..dc6f994 100644 --- a/lib/psych/scalar_scanner.rb +++ b/lib/psych/scalar_scanner.rb @@ -39,19 +39,7 @@ module Psych string end when TIME - date, time = *(string.split(/[ tT]/, 2)) - (yy, m, dd) = date.split('-').map { |x| x.to_i } - md = time.match(/(\d+:\d+:\d+)(\.\d*)?\s*(Z|[-+]\d+(:\d\d)?)?/) - - (hh, mm, ss) = md[1].split(':').map { |x| x.to_i } - us = (md[2] ? Rational(md[2].sub(/^\./, '0.')) : 0) * 1000000 - - time = Time.utc(yy, m, dd, hh, mm, ss, us) - - return time if 'Z' == md[3] - - tz = md[3] ? Integer(md[3].split(':').first.sub(/([-+])0/, '\1')) : 0 - Time.at((time - (tz * 3600)).to_i, us) + parse_time string when /^\d{4}-\d{1,2}-\d{1,2}$/ require 'date' Date.strptime(string, '%Y-%m-%d') @@ -86,5 +74,25 @@ module Psych string end end + + ### + # Parse and return a Time from +string+ + def parse_time string + date, time = *(string.split(/[ tT]/, 2)) + (yy, m, dd) = date.split('-').map { |x| x.to_i } + md = time.match(/(\d+:\d+:\d+)(\.\d*)?\s*(Z|[-+]\d+(:\d\d)?)?/) + + (hh, mm, ss) = md[1].split(':').map { |x| x.to_i } + us = (md[2] ? Rational(md[2].sub(/^\./, '0.')) : 0) * 1000000 + + time = Time.utc(yy, m, dd, hh, mm, ss, us) + + return time if 'Z' == md[3] + return Time.at(time.to_i, us) unless md[3] + + tz = md[3].split(':').map { |digit| Integer(digit, 10) } + offset = tz.first * 3600 + ((tz[1] || 0) * 60) + Time.at((time - offset).to_i, us) + end end end diff --git a/lib/psych/visitors/to_ruby.rb b/lib/psych/visitors/to_ruby.rb index ffff636..745338a 100644 --- a/lib/psych/visitors/to_ruby.rb +++ b/lib/psych/visitors/to_ruby.rb @@ -50,6 +50,9 @@ module Psych o.value.unpack('m').first when '!str', 'tag:yaml.org,2002:str' o.value + when "!ruby/object:DateTime" + require 'date' + @ss.parse_time(o.value).to_datetime when "!ruby/object:Complex" Complex(o.value) when "!ruby/object:Rational" diff --git a/lib/psych/visitors/yaml_tree.rb b/lib/psych/visitors/yaml_tree.rb index 93ccc58..4df7b4d 100644 --- a/lib/psych/visitors/yaml_tree.rb +++ b/lib/psych/visitors/yaml_tree.rb @@ -135,14 +135,14 @@ module Psych @emitter.scalar o.inspect, nil, '!ruby/regexp', false, false, Nodes::Scalar::ANY end - def visit_Time o - formatted = o.strftime("%Y-%m-%d %H:%M:%S") - if o.utc? - formatted += ".%06dZ" % [o.usec] - else - formatted += ".%06d %+.2d:00" % [o.usec, o.gmt_offset / 3600] - end + def visit_DateTime o + formatted = format_time o.to_time + tag = '!ruby/object:DateTime' + @emitter.scalar formatted, nil, tag, false, false, Nodes::Scalar::ANY + end + def visit_Time o + formatted = format_time o @emitter.scalar formatted, nil, nil, true, false, Nodes::Scalar::ANY end @@ -268,6 +268,17 @@ module Psych end private + def format_time time + formatted = time.strftime("%Y-%m-%d %H:%M:%S") + if time.utc? + formatted += ".%09dZ" % [time.nsec] + else + formatted += ".%09d %+.2d:%.2d" % [time.nsec, + time.gmt_offset / 3600, time.gmt_offset % 3600 / 60] + end + formatted + end + # FIXME: remove this method once "to_yaml_properties" is removed def find_ivars target loc = target.method(:to_yaml_properties).source_location.first diff --git a/test/psych/test_date_time.rb b/test/psych/test_date_time.rb new file mode 100644 index 0000000..df66d14 --- /dev/null +++ b/test/psych/test_date_time.rb @@ -0,0 +1,17 @@ +require_relative 'helper' +require 'date' + +module Psych + class TestDateTime < TestCase + def test_string_tag + dt = DateTime.now + yaml = Psych.dump dt + assert_match(/DateTime/, yaml) + end + + def test_round_trip + dt = DateTime.now + assert_cycle dt + end + end +end diff --git a/test/psych/visitors/test_to_ruby.rb b/test/psych/visitors/test_to_ruby.rb index 8ad41db..1a4d319 100644 --- a/test/psych/visitors/test_to_ruby.rb +++ b/test/psych/visitors/test_to_ruby.rb @@ -113,25 +113,25 @@ description: def test_time now = Time.now formatted = now.strftime("%Y-%m-%d %H:%M:%S") + - ".%06d %+.2d:00" % [now.usec, now.gmt_offset / 3600] + ".%09d %+.2d:00" % [now.nsec, now.gmt_offset / 3600] - assert_in_delta now, Nodes::Scalar.new(formatted).to_ruby, 0.000001 + assert_equal now, Nodes::Scalar.new(formatted).to_ruby end def test_time_utc now = Time.now.utc formatted = now.strftime("%Y-%m-%d %H:%M:%S") + - ".%06dZ" % [now.usec] + ".%09dZ" % [now.nsec] - assert_in_delta now, Nodes::Scalar.new(formatted).to_ruby, 0.000001 + assert_equal now, Nodes::Scalar.new(formatted).to_ruby end def test_time_utc_no_z now = Time.now.utc formatted = now.strftime("%Y-%m-%d %H:%M:%S") + - ".%06d" % [now.usec] + ".%09d" % [now.nsec] - assert_in_delta now, Nodes::Scalar.new(formatted).to_ruby, 0.000001 + assert_equal now, Nodes::Scalar.new(formatted).to_ruby end def test_date diff --git a/test/psych/visitors/test_yaml_tree.rb b/test/psych/visitors/test_yaml_tree.rb index 758cfae..ed89e78 100644 --- a/test/psych/visitors/test_yaml_tree.rb +++ b/test/psych/visitors/test_yaml_tree.rb @@ -54,7 +54,7 @@ module Psych def test_time t = Time.now - assert_in_delta t, Psych.load(Psych.dump(t)), 0.000001 + assert_equal t, Psych.load(Psych.dump(t)) end def test_date |