summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAaron Patterson <aaron.patterson@gmail.com>2009-10-06 19:34:57 -0700
committerAaron Patterson <aaron.patterson@gmail.com>2009-10-06 19:34:57 -0700
commit3b4656645f551f0ebe8b5c7e8660992bc88de123 (patch)
tree8672bb435ec295d833c4159e084608818b7c79b9
parentbec41aa80d5977c3f9315e3761f4d364d311960d (diff)
downloadpsych-3b4656645f551f0ebe8b5c7e8660992bc88de123.zip
time can convert to ruby
-rw-r--r--lib/psych/scalar_scanner.rb7
-rw-r--r--lib/psych/visitors/to_ruby.rb13
-rw-r--r--test/test_scalar_scanner.rb11
-rw-r--r--test/visitors/test_to_ruby.rb24
4 files changed, 54 insertions, 1 deletions
diff --git a/lib/psych/scalar_scanner.rb b/lib/psych/scalar_scanner.rb
index 5a038a5..a15096f 100644
--- a/lib/psych/scalar_scanner.rb
+++ b/lib/psych/scalar_scanner.rb
@@ -4,6 +4,9 @@ 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)?)?/
+
def initialize string
@string = string
end
@@ -12,7 +15,9 @@ module Psych
return [:NULL, nil] if @string.empty?
case @string
- when /^\d{4}-\d{2}-\d{2}$/
+ when TIME
+ [:TIME, @string]
+ when /^\d{4}-\d{1,2}-\d{1,2}$/
[:DATE, @string]
when /^\.inf$/i
[:POSITIVE_INFINITY, 1 / 0.0]
diff --git a/lib/psych/visitors/to_ruby.rb b/lib/psych/visitors/to_ruby.rb
index abdfd4c..b4e33ed 100644
--- a/lib/psych/visitors/to_ruby.rb
+++ b/lib/psych/visitors/to_ruby.rb
@@ -35,6 +35,19 @@ module Psych
when :DATE
require 'date'
Date.strptime token.last, '%Y-%m-%d'
+ when :TIME
+ lexeme = token.last
+
+ date, time = *(lexeme.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 }
+
+ time = Time.utc(yy, m, dd, hh, mm, ss)
+
+ tz = (!md[3] || md[3] == 'Z') ? 0 : Integer(md[3].split(':').first)
+ Time.at((time - (tz * 3600)).to_i, md[2].sub(/^\./, '').to_i)
else
token.last
end
diff --git a/test/test_scalar_scanner.rb b/test/test_scalar_scanner.rb
index c3b19aa..4e76082 100644
--- a/test/test_scalar_scanner.rb
+++ b/test/test_scalar_scanner.rb
@@ -2,6 +2,17 @@ require 'minitest/autorun'
require 'psych'
class TestScalarScanner < MiniTest::Unit::TestCase
+ def test_scan_time
+ [ '2001-12-15T02:59:43.1Z',
+ '2001-12-14t21:59:43.10-05:00',
+ '2001-12-14 21:59:43.10 -5',
+ '2001-12-15 2:59:43.10',
+ ].each do |time|
+ ss = Psych::ScalarScanner.new time
+ assert_equal :TIME, ss.tokenize.first
+ end
+ end
+
def test_scan_date
date = '1980-12-16'
ss = Psych::ScalarScanner.new date
diff --git a/test/visitors/test_to_ruby.rb b/test/visitors/test_to_ruby.rb
index c60a9b9..41eae48 100644
--- a/test/visitors/test_to_ruby.rb
+++ b/test/visitors/test_to_ruby.rb
@@ -11,6 +11,30 @@ module Psych
@visitor = ToRuby.new
end
+ def test_time
+ now = Time.now
+ formatted = now.strftime("%Y-%m-%d %H:%M:%S") +
+ ".%06d %d:00" % [now.usec, now.gmt_offset / 3600]
+
+ 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]
+
+ 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]
+
+ assert_equal now, Nodes::Scalar.new(formatted).to_ruby
+ end
+
def test_date
d = '1980-12-16'
actual = Date.strptime(d, '%Y-%m-%d')