[ruby-core:121448] [Ruby Bug#21199] Psych.dump and load on Date before 1582-10-15

Issue #21199 has been reported by fitmap (Justin Peal). ---------------------------------------- Bug #21199: Psych.dump and load on Date before 1582-10-15 https://bugs.ruby-lang.org/issues/21199 * Author: fitmap (Justin Peal) * Status: Open * ruby -v: ruby 3.2.2 (2023-03-30 revision e51014f9c0) [x64-mingw-ucrt] * Backport: 3.1: UNKNOWN, 3.2: UNKNOWN, 3.3: UNKNOWN, 3.4: UNKNOWN ---------------------------------------- The code is: require 'date' require 'psych' date = Date.new(1582, 10, 4) p "date=#{date.inspect}" str = Psych.dump(date, permitted_classes: [Date]) p "str=#{str}" date2 = Psych.load(str, permitted_classes: [Date]) p "date2=#{date2.inspect}" The output is: "date=#<Date: 1582-10-04 ((2299160j,0s,0n),+0s,2299161j)>" "str=--- 1582-10-14\n" "date2=#<Date: 1582-10-14 ((2299160j,0s,0n),+0s,-Infj)>" -- https://bugs.ruby-lang.org/

Issue #21199 has been updated by mame (Yusuke Endoh). Status changed from Open to Feedback Note that `date` and `date2` are equal in your reproduction code. ```ruby require 'date' require 'psych' date = Date.new(1582, 10, 4) p "date=#{date.inspect}" str = Psych.dump(date, permitted_classes: [Date]) p "str=#{str}" date2 = Psych.load(str, permitted_classes: [Date]) p "date2=#{date2.inspect}" p date == date2 #=> true ``` The issue is that YAML cannot retain calendar information. When Psych serializes a `Date` object, it converts it to `Date::GREGORIAN` (the proleptic Gregorian calendar). As a result, the serialized YAML contains `--- 1582-10-14`, which is intentional. When deserializing a `Date` from YAML, a `Date::GREGORIAN` Date object is generated. I believe it would be possible to convert it to an `Date::ITALY` Date object by default. However, consider a case where a user manually writes `--- 1582-10-14` in YAML and loads it with Psych. They would then get `Date.new(1582, 10, 4)`, which could be an unexpected result. For this reason, I thinkg the current behavior is unavoidable. If you have a specific proposal on how to fix it, please write it. ---------------------------------------- Bug #21199: Psych.dump and load on Date before 1582-10-15 https://bugs.ruby-lang.org/issues/21199#change-112448 * Author: fitmap (Justin Peal) * Status: Feedback * ruby -v: ruby 3.2.2 (2023-03-30 revision e51014f9c0) [x64-mingw-ucrt] * Backport: 3.1: UNKNOWN, 3.2: UNKNOWN, 3.3: UNKNOWN, 3.4: UNKNOWN ---------------------------------------- The code is: require 'date' require 'psych' date = Date.new(1582, 10, 4) p "date=#{date.inspect}" str = Psych.dump(date, permitted_classes: [Date]) p "str=#{str}" date2 = Psych.load(str, permitted_classes: [Date]) p "date2=#{date2.inspect}" The output is: "date=#<Date: 1582-10-04 ((2299160j,0s,0n),+0s,2299161j)>" "str=--- 1582-10-14\n" "date2=#<Date: 1582-10-14 ((2299160j,0s,0n),+0s,-Infj)>" -- https://bugs.ruby-lang.org/

Issue #21199 has been updated by fitmap (Justin Peal). I suggest Psych.dump and Psych.load should deal the date as the default style Date::ITALY, like Date.new. Normal people only know Date::ITALY, which skip 1582-10-05~1582-10-14. I also suggest Date.to_s should convert inner date style to Date::ITALY, then output it. ''' require 'date' require 'psych' date1 = Date.new(1582, 10, 4) str = Psych.dump(date1, permitted_classes: [Date]) date2 = Psych.load(str, permitted_classes: [Date]) puts "date1=#{date1}, After dump and load, date2=#{date2}" ''' date1=1582-10-04, After dump and load, date2=1582-10-14 ---------------------------------------- Bug #21199: Psych.dump and load on Date before 1582-10-15 https://bugs.ruby-lang.org/issues/21199#change-112467 * Author: fitmap (Justin Peal) * Status: Feedback * ruby -v: ruby 3.2.2 (2023-03-30 revision e51014f9c0) [x64-mingw-ucrt] * Backport: 3.1: UNKNOWN, 3.2: UNKNOWN, 3.3: UNKNOWN, 3.4: UNKNOWN ---------------------------------------- The code is: ```ruby require 'date' require 'psych' date = Date.new(1582, 10, 4) p "date=#{date.inspect}" str = Psych.dump(date, permitted_classes: [Date]) p "str=#{str}" date2 = Psych.load(str, permitted_classes: [Date]) p "date2=#{date2.inspect}" ``` The output is: ``` "date=#<Date: 1582-10-04 ((2299160j,0s,0n),+0s,2299161j)>" "str=--- 1582-10-14\n" "date2=#<Date: 1582-10-14 ((2299160j,0s,0n),+0s,-Infj)>" ``` -- https://bugs.ruby-lang.org/

Issue #21199 has been updated by nobu (Nobuyoshi Nakada). Status changed from Feedback to Third Party's Issue Backport changed from 3.1: UNKNOWN, 3.2: UNKNOWN, 3.3: UNKNOWN, 3.4: UNKNOWN to 3.1: DONTNEED, 3.2: DONTNEED, 3.3: DONTNEED, 3.4: DONTNEED YAML has no specification of calendar systems. If YAML specifies it, we would obey it of course. Until then, YAML is not suitable for such dates, just don't use such dates. ---------------------------------------- Bug #21199: Psych.dump and load on Date before 1582-10-15 https://bugs.ruby-lang.org/issues/21199#change-112469 * Author: fitmap (Justin Peal) * Status: Third Party's Issue * ruby -v: ruby 3.2.2 (2023-03-30 revision e51014f9c0) [x64-mingw-ucrt] * Backport: 3.1: DONTNEED, 3.2: DONTNEED, 3.3: DONTNEED, 3.4: DONTNEED ---------------------------------------- The code is: ```ruby require 'date' require 'psych' date = Date.new(1582, 10, 4) p "date=#{date.inspect}" str = Psych.dump(date, permitted_classes: [Date]) p "str=#{str}" date2 = Psych.load(str, permitted_classes: [Date]) p "date2=#{date2.inspect}" ``` The output is: ``` "date=#<Date: 1582-10-04 ((2299160j,0s,0n),+0s,2299161j)>" "str=--- 1582-10-14\n" "date2=#<Date: 1582-10-14 ((2299160j,0s,0n),+0s,-Infj)>" ``` -- https://bugs.ruby-lang.org/
participants (3)
-
fitmap (Justin Peal)
-
mame (Yusuke Endoh)
-
nobu (Nobuyoshi Nakada)