[前][次][番号順一覧][スレッド一覧]

ruby-changes:16540

From: tenderlove <ko1@a...>
Date: Sat, 3 Jul 2010 09:53:02 +0900 (JST)
Subject: [ruby-changes:16540] Ruby:r28532 (trunk): * ext/psych/lib/psych/visitors/to_ruby.rb(visit_Psych_Nodes_Scalar):

tenderlove	2010-07-03 09:52:43 +0900 (Sat, 03 Jul 2010)

  New Revision: 28532

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=28532

  Log:
    * ext/psych/lib/psych/visitors/to_ruby.rb(visit_Psych_Nodes_Scalar):
      teaching Psych to deserialize DateTime objects. [Bug #1390]
    
    * ext/psych/lib/psych/visitors/yaml_tree.rb(visit_DateTime): added a
      method for serializing DateTime objects.
    
    * ext/psych/lib/psych/scalar_scanner.rb(parse_time): add method for
      parsing times objects from a string.
    
    * test/psych/test_date_time.rb: tests for dumping DateTime objects.

  Added files:
    trunk/test/psych/test_date_time.rb
  Modified files:
    trunk/ChangeLog
    trunk/ext/psych/lib/psych/scalar_scanner.rb
    trunk/ext/psych/lib/psych/visitors/to_ruby.rb
    trunk/ext/psych/lib/psych/visitors/yaml_tree.rb

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 28531)
+++ ChangeLog	(revision 28532)
@@ -1,3 +1,16 @@
+Sat Jul  3 09:47:26 2010  Aaron Patterson <aaron@t...>
+
+	* ext/psych/lib/psych/visitors/to_ruby.rb(visit_Psych_Nodes_Scalar):
+	  teaching Psych to deserialize DateTime objects. [Bug #1390]
+
+	* ext/psych/lib/psych/visitors/yaml_tree.rb(visit_DateTime): added a
+	  method for serializing DateTime objects.
+
+	* ext/psych/lib/psych/scalar_scanner.rb(parse_time): add method for
+	  parsing times objects from a string.
+	
+	* test/psych/test_date_time.rb: tests for dumping DateTime objects.
+
 Sat Jul  3 09:13:55 2010  Aaron Patterson <aaron@t...>
 
 	* ext/psych/lib/psych/visitors/yaml_tree.rb (visit_Time): use
Index: ext/psych/lib/psych/scalar_scanner.rb
===================================================================
--- ext/psych/lib/psych/scalar_scanner.rb	(revision 28531)
+++ ext/psych/lib/psych/scalar_scanner.rb	(revision 28532)
@@ -39,19 +39,7 @@
           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,23 @@
         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]
+
+      tz = md[3] ? Integer(md[3].split(':').first.sub(/([-+])0/, '\1')) : 0
+      Time.at((time - (tz * 3600)).to_i, us)
+    end
   end
 end
Index: ext/psych/lib/psych/visitors/yaml_tree.rb
===================================================================
--- ext/psych/lib/psych/visitors/yaml_tree.rb	(revision 28531)
+++ ext/psych/lib/psych/visitors/yaml_tree.rb	(revision 28532)
@@ -135,6 +135,19 @@
         @emitter.scalar o.inspect, nil, '!ruby/regexp', false, false, Nodes::Scalar::ANY
       end
 
+      def visit_DateTime o
+        o = o.to_time
+        formatted = o.strftime("%Y-%m-%d %H:%M:%S")
+        if o.utc?
+          formatted += ".%06dZ" % [o.nsec]
+        else
+          formatted += ".%06d %+.2d:00" % [o.nsec, o.gmt_offset / 3600]
+        end
+
+        tag = '!ruby/object:DateTime'
+        @emitter.scalar formatted, nil, tag, false, false, Nodes::Scalar::ANY
+      end
+
       def visit_Time o
         formatted = o.strftime("%Y-%m-%d %H:%M:%S")
         if o.utc?
Index: ext/psych/lib/psych/visitors/to_ruby.rb
===================================================================
--- ext/psych/lib/psych/visitors/to_ruby.rb	(revision 28531)
+++ ext/psych/lib/psych/visitors/to_ruby.rb	(revision 28532)
@@ -50,6 +50,9 @@
           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"
Index: test/psych/test_date_time.rb
===================================================================
--- test/psych/test_date_time.rb	(revision 0)
+++ test/psych/test_date_time.rb	(revision 28532)
@@ -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

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]