ruby-changes:72860
From: Nobuyoshi <ko1@a...>
Date: Mon, 8 Aug 2022 23:50:26 +0900 (JST)
Subject: [ruby-changes:72860] e07d450dea (master): [ruby/date] Fix Time#to_datetime before calendar reform
https://git.ruby-lang.org/ruby.git/commit/?id=e07d450dea From e07d450deae500422b7693a30c75c5b1567601a2 Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada <nobu@r...> Date: Mon, 8 Aug 2022 22:43:56 +0900 Subject: [ruby/date] Fix Time#to_datetime before calendar reform Time is always in the proleptic Gregorian calendar. Also DateTime#to_time should convert to the Gregorian calendar first, before extracting its components. https://bugs.ruby-lang.org/issues/18946#change-98527 https://github.com/ruby/date/commit/b2aee75248 --- ext/date/date_core.c | 13 +++++++++---- test/date/test_date_conv.rb | 17 +++++++++++++++++ 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/ext/date/date_core.c b/ext/date/date_core.c index 1c0d1c4920..c68f70e5f8 100644 --- a/ext/date/date_core.c +++ b/ext/date/date_core.c @@ -8811,7 +8811,7 @@ time_to_datetime(VALUE self) https://github.com/ruby/ruby/blob/trunk/ext/date/date_core.c#L8811 ret = d_complex_new_internal(cDateTime, nth, 0, 0, sf, - of, DEFAULT_SG, + of, GREGORIAN, ry, m, d, h, min, s, HAVE_CIVIL | HAVE_TIME); @@ -8915,12 +8915,17 @@ date_to_datetime(VALUE self) https://github.com/ruby/ruby/blob/trunk/ext/date/date_core.c#L8915 static VALUE datetime_to_time(VALUE self) { - volatile VALUE dup = dup_obj(self); + get_d1(self); + + if (m_julian_p(dat)) { + self = d_lite_gregorian(self); + get_d1a(self); + dat = adat; + } + { VALUE t; - get_d1(dup); - t = rb_funcall(rb_cTime, rb_intern("new"), 7, diff --git a/test/date/test_date_conv.rb b/test/date/test_date_conv.rb index d41ff45d85..ed478b41bb 100644 --- a/test/date/test_date_conv.rb +++ b/test/date/test_date_conv.rb @@ -77,6 +77,11 @@ class TestDateConv < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/date/test_date_conv.rb#L77 assert_equal([2004, 9, 19, 1, 2, 3, 456789], [t.year, t.mon, t.mday, t.hour, t.min, t.sec, t.usec]) + d = DateTime.new(1582, 10, 3, 1, 2, 3, 0) + 456789.to_r/86400000000 + t = d.to_time.utc + assert_equal([1582, 10, 13, 1, 2, 3, 456789], + [t.year, t.mon, t.mday, t.hour, t.min, t.sec, t.usec]) + if Time.allocate.respond_to?(:nsec) d = DateTime.new(2004, 9, 19, 1, 2, 3, 0) + 456789123.to_r/86400000000000 t = d.to_time.utc @@ -100,6 +105,10 @@ class TestDateConv < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/date/test_date_conv.rb#L105 t = Time.utc(2004, 9, 19, 1, 2, 3, 456789) d = t.to_date assert_equal([2004, 9, 19, 0], [d.year, d.mon, d.mday, d.day_fraction]) + + t = Time.utc(1582, 10, 13, 1, 2, 3, 456789) + d = t.to_date # using ITALY + assert_equal([1582, 10, 3, 0], [d.year, d.mon, d.mday, d.day_fraction]) end def test_to_date__from_date @@ -136,6 +145,14 @@ class TestDateConv < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/date/test_date_conv.rb#L145 [d.year, d.mon, d.mday, d.hour, d.min, d.sec, d.sec_fraction, d.offset]) + t = Time.utc(1582, 10, 13, 1, 2, 3, 456789) + d = t.to_datetime # using ITALY + assert_equal([1582, 10, 3, 1, 2, 3, + 456789.to_r/1000000, + 0], + [d.year, d.mon, d.mday, d.hour, d.min, d.sec, + d.sec_fraction, d.offset]) + t = Time.now d = t.to_datetime require 'time' -- cgit v1.2.1 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/