Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 22 additions & 4 deletions ext/date/date_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ typedef long rb_len_t;

#define USE_PACK

#ifndef HAVE_RB_CATEGORY_WARN
#define rb_category_warn(category, fmt) rb_warn(fmt)
#endif

static ID id_cmp, id_le_p, id_ge_p, id_eqeq_p;
static VALUE cDate, cDateTime;
static VALUE eDateError;
Expand Down Expand Up @@ -4683,10 +4687,6 @@ get_limit(VALUE opt)
return 128;
}

#ifndef HAVE_RB_CATEGORY_WARN
#define rb_category_warn(category, fmt) rb_warn(fmt)
#endif

static VALUE
check_limit(VALUE str, VALUE opt)
{
Expand Down Expand Up @@ -6155,13 +6155,24 @@ d_lite_new_offset(int argc, VALUE *argv, VALUE self)
return dup_obj_with_new_offset(self, rof);
}

static void
check_date_fraction(VALUE self)
{
if (!f_kind_of_p(self, cDateTime))
rb_category_warn(RB_WARN_CATEGORY_DEPRECATED,
"Date with fractional day is deprecated, "
"use DateTime if you need a fractional day");
}

/*
* call-seq:
* d + other -> date
*
* Returns a date object pointing +other+ days after self. The other
* should be a numeric value. If the other is a fractional number,
* assumes its precision is at most nanosecond.
* Passing a fractional number to Date#+ is deprecated; use DateTime
* if you need a fractional day.
*
* Date.new(2001,2,3) + 1 #=> #<Date: 2001-02-04 ...>
* DateTime.new(2001,2,3) + Rational(1,2)
Expand Down Expand Up @@ -6291,6 +6302,9 @@ d_lite_plus(VALUE self, VALUE other)

o = RFLOAT_VALUE(other);

if (modf(o, &tmp) != 0.0)
check_date_fraction(self);

if (o > 0)
s = +1;
else {
Expand Down Expand Up @@ -6403,6 +6417,8 @@ d_lite_plus(VALUE self, VALUE other)
goto again;
}

check_date_fraction(self);

if (f_positive_p(other))
s = +1;
else {
Expand Down Expand Up @@ -6553,6 +6569,8 @@ minus_dd(VALUE self, VALUE other)
* pointing +other+ days before self.
* If the other is a fractional number,
* assumes its precision is at most nanosecond.
* Passing a fractional number to Date#- is deprecated; use DateTime
* if you need a fractional day.
*
* Date.new(2001,2,3) - 1 #=> #<Date: 2001-02-02 ...>
* DateTime.new(2001,2,3) - Rational(1,2)
Expand Down
45 changes: 45 additions & 0 deletions test/date/test_date_arith.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,51 @@ def test__plus
[d.year, d.mon, d.mday, d.hour, d.min, d.sec])
end

def test_fractional_day_deprecated
pat = /Date with fractional day is deprecated/
d = Date.new(2001, 2, 3)

[
-> { Date.new(2001, 2, 3.5) },
-> { Date.civil(2001, 2, Rational(7, 2)) },
-> { Date.jd(2451944.5) },
-> { Date.ordinal(2001, 34.5) },
-> { Date.commercial(2001, 5, Rational(3, 2)) },
-> { d + 0.5 },
-> { d + Rational(1, 2) },
-> { d - 0.5 },
-> { d - Rational(1, 2) },
-> { d.next_day(0.5) },
-> { d.prev_day(Rational(1, 2)) },
-> { d.step(d + 1, 0.5).to_a },
].each do |pr|
assert_deprecated_warn(pat, &pr)
end

dt = DateTime.new(2001, 2, 3)
[
-> { Date.new(2001, 2, 3.0) },
-> { Date.jd(Rational(2451944)) },
-> { d + 1 },
-> { d + 1.0 },
-> { d + Rational(2, 1) },
-> { d - 1.0 },
-> { d >> 1 },
-> { d << 1 },
-> { d.next_day(2) },
-> { DateTime.new(2001, 2, 3.5) },
-> { DateTime.jd(2451944.5) },
-> { DateTime.ordinal(2001, 34.5) },
-> { DateTime.commercial(2001, 5, Rational(3, 2)) },
-> { dt + 0.5 },
-> { dt - Rational(1, 2) },
-> { dt.next_day(0.5) },
-> { dt.step(dt + 1, 0.5).to_a },
].each do |pr|
assert_deprecated_warn("", &pr)
end
end

def test__plus__ex
e = TypeError
assert_raise(e) do
Expand Down
4 changes: 2 additions & 2 deletions test/date/test_date_conv.rb
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ def test_to_date__from_time
end

def test_to_date__from_date
d = Date.new(2004, 9, 19) + 1.to_r/2
d = assert_deprecated_warn(/fractional day/) { Date.new(2004, 9, 19) + 1.to_r/2 }
d2 = d.to_date
assert_equal([2004, 9, 19, 1.to_r/2],
[d2.year, d2.mon, d2.mday, d2.day_fraction])
Expand Down Expand Up @@ -159,7 +159,7 @@ def test_to_datetime__from_time
end

def test_to_datetime__from_date
d = Date.new(2004, 9, 19) + 1.to_r/2
d = assert_deprecated_warn(/fractional day/) { Date.new(2004, 9, 19) + 1.to_r/2 }
d2 = d.to_datetime
assert_equal([2004, 9, 19, 0, 0, 0, 0, 0],
[d2.year, d2.mon, d2.mday, d2.hour, d2.min, d2.sec,
Expand Down
2 changes: 1 addition & 1 deletion test/date/test_date_marshal.rb
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ def test_marshal
expected_error = defined?(FrozenError) ? FrozenError : RuntimeError
assert_raise(expected_error){d.marshal_load(a)}

d = Date.new + 1/2r + 2304/65437r/86400
d = assert_deprecated_warn(/fractional day/) { Date.new + 1/2r + 2304/65437r/86400 }
m = Marshal.dump(d)
d2 = Marshal.load(m)
assert_equal(d, d2)
Expand Down
10 changes: 5 additions & 5 deletions test/date/test_switch_hitter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ def test_new

d = Date.new(2001, 2, 3)
assert_equal([2001, 2, 3], [d.year, d.mon, d.mday])
d = Date.new(2001, 2, Rational('3.5'))
d = assert_deprecated_warn(/fractional day/) { Date.new(2001, 2, Rational('3.5')) }
assert_equal([2001, 2, 3], [d.year, d.mon, d.mday])
d = Date.new(2001,2, 3, Date::JULIAN)
assert_equal([2001, 2, 3], [d.year, d.mon, d.mday])
Expand Down Expand Up @@ -191,18 +191,18 @@ def test_fractional
assert_equal(2451944, d.jd)
d = Date.jd(Rational(2451944))
assert_equal(2451944, d.jd)
d = Date.jd(2451944.5)
d = assert_deprecated_warn(/fractional day/) { Date.jd(2451944.5) }
assert_equal(2451944, d.jd)
d = Date.jd(Rational('2451944.5'))
d = assert_deprecated_warn(/fractional day/) { Date.jd(Rational('2451944.5')) }
assert_equal(2451944, d.jd)

d = Date.civil(2001, 2, 3.0)
assert_equal([2001, 2, 3], [d.year, d.mon, d.mday])
d = Date.civil(2001, 2, Rational(3))
assert_equal([2001, 2, 3], [d.year, d.mon, d.mday])
d = Date.civil(2001, 2, 3.5)
d = assert_deprecated_warn(/fractional day/) { Date.civil(2001, 2, 3.5) }
assert_equal([2001, 2, 3], [d.year, d.mon, d.mday])
d = Date.civil(2001, 2, Rational('3.5'))
d = assert_deprecated_warn(/fractional day/) { Date.civil(2001, 2, Rational('3.5')) }
assert_equal([2001, 2, 3], [d.year, d.mon, d.mday])

d = Date.ordinal(2001, 2.0)
Expand Down
Loading