From cbdde8e0c574f19e170c3de05dd0bbd276acb741 Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada 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 ++++++++-------- 3 files changed, 12 insertions(+), 10 deletions(-) (limited to 'ext/psych') 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 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 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 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 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 @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") -- cgit v1.2.3