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

ruby-changes:73459

From: Nobuyoshi <ko1@a...>
Date: Wed, 7 Sep 2022 09:44:24 +0900 (JST)
Subject: [ruby-changes:73459] cbdde8e0c5 (master): [ruby/psych] Dump Date/DateTime as proleptic Gregorian date as well as Time

https://git.ruby-lang.org/ruby.git/commit/?id=cbdde8e0c5

From cbdde8e0c574f19e170c3de05dd0bbd276acb741 Mon Sep 17 00:00:00 2001
From: Nobuyoshi Nakada <nobu@r...>
Date: Tue, 9 Aug 2022 09:22:53 +0900
Subject: [ruby/psych] Dump Date/DateTime as proleptic Gregorian date as well
 as Time

Fix ruby/psych#572

https://github.com/ruby/psych/commit/92304269bc
---
 ext/psych/lib/psych/scalar_scanner.rb     |  2 +-
 ext/psych/lib/psych/visitors/to_ruby.rb   |  4 +++-
 ext/psych/lib/psych/visitors/yaml_tree.rb | 16 ++++++++--------
 test/psych/test_date_time.rb              | 20 ++++++++++++++++++++
 4 files changed, 32 insertions(+), 10 deletions(-)

diff --git a/ext/psych/lib/psych/scalar_scanner.rb b/ext/psych/lib/psych/scalar_scanner.rb
index b50667c315..3cb4bf3c7e 100644
--- a/ext/psych/lib/psych/scalar_scanner.rb
+++ b/ext/psych/lib/psych/scalar_scanner.rb
@@ -63,7 +63,7 @@ module Psych https://github.com/ruby/ruby/blob/trunk/ext/psych/lib/psych/scalar_scanner.rb#L63
       elsif string.match?(/^\d{4}-(?:1[012]|0\d|\d)-(?:[12]\d|3[01]|0\d|\d)$/)
         require 'date'
         begin
-          class_loader.date.strptime(string, '%Y-%m-%d')
+          class_loader.date.strptime(string, '%F', Date::GREGORIAN)
         rescue ArgumentError
           string
         end
diff --git a/ext/psych/lib/psych/visitors/to_ruby.rb b/ext/psych/lib/psych/visitors/to_ruby.rb
index cce5daf3bb..8614251ca9 100644
--- a/ext/psych/lib/psych/visitors/to_ruby.rb
+++ b/ext/psych/lib/psych/visitors/to_ruby.rb
@@ -80,7 +80,9 @@ module Psych https://github.com/ruby/ruby/blob/trunk/ext/psych/lib/psych/visitors/to_ruby.rb#L80
         when "!ruby/object:DateTime"
           class_loader.date_time
           require 'date' unless defined? DateTime
-          @ss.parse_time(o.value).to_datetime
+          t = @ss.parse_time(o.value)
+          DateTime.civil(*t.to_a[0, 6].reverse, Rational(t.utc_offset, 86400)) +
+            (t.subsec/86400)
         when '!ruby/encoding'
           ::Encoding.find o.value
         when "!ruby/object:Complex"
diff --git a/ext/psych/lib/psych/visitors/yaml_tree.rb b/ext/psych/lib/psych/visitors/yaml_tree.rb
index 316a3a9496..31858798e4 100644
--- a/ext/psych/lib/psych/visitors/yaml_tree.rb
+++ b/ext/psych/lib/psych/visitors/yaml_tree.rb
@@ -192,12 +192,13 @@ module Psych https://github.com/ruby/ruby/blob/trunk/ext/psych/lib/psych/visitors/yaml_tree.rb#L192
         register o, @emitter.scalar(o.inspect, nil, '!ruby/regexp', false, false, Nodes::Scalar::ANY)
       end
 
+      def visit_Date o
+        register o, visit_Integer(o.gregorian)
+      end
+
       def visit_DateTime o
-        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
+        t = o.italy
+        formatted = format_time t, t.offset.zero?
         tag = '!ruby/object:DateTime'
         register o, @emitter.scalar(formatted, nil, tag, false, false, Nodes::Scalar::ANY)
       end
@@ -235,7 +236,6 @@ module Psych https://github.com/ruby/ruby/blob/trunk/ext/psych/lib/psych/visitors/yaml_tree.rb#L236
       end
       alias :visit_TrueClass :visit_Integer
       alias :visit_FalseClass :visit_Integer
-      alias :visit_Date :visit_Integer
 
       def visit_Float o
         if o.nan?
@@ -482,8 +482,8 @@ module Psych https://github.com/ruby/ruby/blob/trunk/ext/psych/lib/psych/visitors/yaml_tree.rb#L482
         @emitter.end_mapping
       end
 
-      def format_time time
-        if time.utc?
+      def format_time time, utc = time.utc?
+        if utc
           time.strftime("%Y-%m-%d %H:%M:%S.%9N Z")
         else
           time.strftime("%Y-%m-%d %H:%M:%S.%9N %:z")
diff --git a/test/psych/test_date_time.rb b/test/psych/test_date_time.rb
index 6f1e8b509e..3379bd24bf 100644
--- a/test/psych/test_date_time.rb
+++ b/test/psych/test_date_time.rb
@@ -44,6 +44,26 @@ module Psych https://github.com/ruby/ruby/blob/trunk/test/psych/test_date_time.rb#L44
       assert_match(/12:00:00-05:00/,  cycled.last.to_s)
     end
 
+    def test_julian_date
+      d = Date.new(1582, 10, 4, Date::GREGORIAN)
+      assert_cycle d
+    end
+
+    def test_proleptic_gregorian_date
+      d = Date.new(1582, 10, 14, Date::GREGORIAN)
+      assert_cycle d
+    end
+
+    def test_julian_datetime
+      dt = DateTime.new(1582, 10, 4, 23, 58, 59, 0, Date::GREGORIAN)
+      assert_cycle dt
+    end
+
+    def test_proleptic_gregorian_datetime
+      dt = DateTime.new(1582, 10, 14, 23, 58, 59, 0, Date::GREGORIAN)
+      assert_cycle dt
+    end
+
     def test_invalid_date
       assert_cycle "2013-10-31T10:40:07-000000000000033"
     end
-- 
cgit v1.2.1


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

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