Skip to content

Commit b2aee75

Browse files
committed
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
1 parent 11ebe3d commit b2aee75

File tree

2 files changed

+26
-4
lines changed

2 files changed

+26
-4
lines changed

ext/date/date_core.c

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8811,7 +8811,7 @@ time_to_datetime(VALUE self)
88118811
ret = d_complex_new_internal(cDateTime,
88128812
nth, 0,
88138813
0, sf,
8814-
of, DEFAULT_SG,
8814+
of, GREGORIAN,
88158815
ry, m, d,
88168816
h, min, s,
88178817
HAVE_CIVIL | HAVE_TIME);
@@ -8915,12 +8915,17 @@ date_to_datetime(VALUE self)
89158915
static VALUE
89168916
datetime_to_time(VALUE self)
89178917
{
8918-
volatile VALUE dup = dup_obj(self);
8918+
get_d1(self);
8919+
8920+
if (m_julian_p(dat)) {
8921+
self = d_lite_gregorian(self);
8922+
get_d1a(self);
8923+
dat = adat;
8924+
}
8925+
89198926
{
89208927
VALUE t;
89218928

8922-
get_d1(dup);
8923-
89248929
t = rb_funcall(rb_cTime,
89258930
rb_intern("new"),
89268931
7,

test/date/test_date_conv.rb

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,11 @@ def test_to_time__from_datetime
7777
assert_equal([2004, 9, 19, 1, 2, 3, 456789],
7878
[t.year, t.mon, t.mday, t.hour, t.min, t.sec, t.usec])
7979

80+
d = DateTime.new(1582, 10, 3, 1, 2, 3, 0) + 456789.to_r/86400000000
81+
t = d.to_time.utc
82+
assert_equal([1582, 10, 13, 1, 2, 3, 456789],
83+
[t.year, t.mon, t.mday, t.hour, t.min, t.sec, t.usec])
84+
8085
if Time.allocate.respond_to?(:nsec)
8186
d = DateTime.new(2004, 9, 19, 1, 2, 3, 0) + 456789123.to_r/86400000000000
8287
t = d.to_time.utc
@@ -100,6 +105,10 @@ def test_to_date__from_time
100105
t = Time.utc(2004, 9, 19, 1, 2, 3, 456789)
101106
d = t.to_date
102107
assert_equal([2004, 9, 19, 0], [d.year, d.mon, d.mday, d.day_fraction])
108+
109+
t = Time.utc(1582, 10, 13, 1, 2, 3, 456789)
110+
d = t.to_date # using ITALY
111+
assert_equal([1582, 10, 3, 0], [d.year, d.mon, d.mday, d.day_fraction])
103112
end
104113

105114
def test_to_date__from_date
@@ -136,6 +145,14 @@ def test_to_datetime__from_time
136145
[d.year, d.mon, d.mday, d.hour, d.min, d.sec,
137146
d.sec_fraction, d.offset])
138147

148+
t = Time.utc(1582, 10, 13, 1, 2, 3, 456789)
149+
d = t.to_datetime # using ITALY
150+
assert_equal([1582, 10, 3, 1, 2, 3,
151+
456789.to_r/1000000,
152+
0],
153+
[d.year, d.mon, d.mday, d.hour, d.min, d.sec,
154+
d.sec_fraction, d.offset])
155+
139156
t = Time.now
140157
d = t.to_datetime
141158
require 'time'

0 commit comments

Comments
 (0)