summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAaron Patterson <aaron.patterson@gmail.com>2010-07-05 16:19:26 -0700
committerAaron Patterson <aaron.patterson@gmail.com>2010-07-05 16:19:26 -0700
commit2c2b6e72b18fc6666b218837016b0be9d29c48ce (patch)
tree10473be8a4b275b837b35df903274ccac9948765
parentcfa3a13770b4ebb9a5ef4cf168f80f796b84ca3a (diff)
downloadpsych-2c2b6e72b18fc6666b218837016b0be9d29c48ce.zip
merging changes from ruby
-rw-r--r--lib/psych/scalar_scanner.rb34
-rw-r--r--lib/psych/visitors/to_ruby.rb3
-rw-r--r--lib/psych/visitors/yaml_tree.rb25
-rw-r--r--test/psych/test_date_time.rb17
-rw-r--r--test/psych/visitors/test_to_ruby.rb12
-rw-r--r--test/psych/visitors/test_yaml_tree.rb2
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