summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAaron Patterson <aaron.patterson@gmail.com>2013-11-26 13:43:10 -0800
committerAaron Patterson <aaron.patterson@gmail.com>2013-11-26 13:43:10 -0800
commit1029c92983fc2cf90107accb73cf69d206099694 (patch)
treed2ed870ca161882de0efdc4c2673d8a8b93fa8ac
parent6066fcc8d8d49ed22538cf33e2c3da61334d55b2 (diff)
downloadpsych-1029c92983fc2cf90107accb73cf69d206099694.zip
fix support for negative years.
Fixes #168
-rw-r--r--CHANGELOG.rdoc8
-rw-r--r--lib/psych/scalar_scanner.rb4
-rw-r--r--lib/psych/visitors/yaml_tree.rb6
-rw-r--r--test/psych/test_date_time.rb9
4 files changed, 24 insertions, 3 deletions
diff --git a/CHANGELOG.rdoc b/CHANGELOG.rdoc
index 3647c57..830e43d 100644
--- a/CHANGELOG.rdoc
+++ b/CHANGELOG.rdoc
@@ -1,3 +1,11 @@
+Wed Nov 27 06:40:18 2013 Aaron Patterson <aaron@tenderlovemaking.com>
+
+ * ext/psych/lib/psych/scalar_scanner.rb: fix support for negative
+ years.
+ * ext/psych/lib/psych/visitors/yaml_tree.rb: ditto
+ * test/psych/test_date_time.rb: test for change.
+ Fixes: https://github.com/tenderlove/psych/issues/168
+
Wed Nov 27 04:46:55 2013 Aaron Patterson <aaron@tenderlovemaking.com>
* ext/psych/lib/psych/scalar_scanner.rb: fix regexp for matching TIME
diff --git a/lib/psych/scalar_scanner.rb b/lib/psych/scalar_scanner.rb
index 5a80598..3fc9edd 100644
--- a/lib/psych/scalar_scanner.rb
+++ b/lib/psych/scalar_scanner.rb
@@ -5,7 +5,7 @@ module Psych
# Scan scalars for built in types
class ScalarScanner
# Taken from http://yaml.org/type/timestamp.html
- TIME = /^\d{4}-\d{1,2}-\d{1,2}(?:[Tt]|\s+)\d{1,2}:\d\d:\d\d(?:\.\d*)?(?:\s*(?:Z|[-+]\d{1,2}:?(?:\d\d)?))?$/
+ TIME = /^-?\d{4}-\d{1,2}-\d{1,2}(?:[Tt]|\s+)\d{1,2}:\d\d:\d\d(?:\.\d*)?(?:\s*(?:Z|[-+]\d{1,2}:?(?:\d\d)?))?$/
# Taken from http://yaml.org/type/float.html
FLOAT = /^(?:[-+]?([0-9][0-9_,]*)?\.[0-9]*([eE][-+][0-9]+)?(?# base 10)
@@ -123,7 +123,7 @@ module Psych
klass = class_loader.load 'Time'
date, time = *(string.split(/[ tT]/, 2))
- (yy, m, dd) = date.split('-').map { |x| x.to_i }
+ (yy, m, dd) = date.match(/^(-?\d{4})-(\d{1,2})-(\d{1,2})/).captures.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 }
diff --git a/lib/psych/visitors/yaml_tree.rb b/lib/psych/visitors/yaml_tree.rb
index b469e2d..1cb2137 100644
--- a/lib/psych/visitors/yaml_tree.rb
+++ b/lib/psych/visitors/yaml_tree.rb
@@ -209,7 +209,11 @@ module Psych
end
def visit_DateTime o
- formatted = format_time o.to_time
+ formatted = if o.offset.zero?
+ o.strftime("%Y-%m-%d %H:%M:%S.%9N Z".freeze)
+ else
+ o.strftime("%Y-%m-%d %H:%M:%S.%9N %:z".freeze)
+ end
tag = '!ruby/object:DateTime'
register o, @emitter.scalar(formatted, nil, tag, false, false, Nodes::Scalar::ANY)
end
diff --git a/test/psych/test_date_time.rb b/test/psych/test_date_time.rb
index 91de6a4..72150ad 100644
--- a/test/psych/test_date_time.rb
+++ b/test/psych/test_date_time.rb
@@ -3,6 +3,15 @@ require 'date'
module Psych
class TestDateTime < TestCase
+ def test_negative_year
+ time = Time.utc -1, 12, 16
+ assert_cycle time
+ end
+
+ def test_new_datetime
+ assert_cycle DateTime.new
+ end
+
def test_invalid_date
assert_cycle "2013-10-31T10:40:07-000000000000033"
end