ruby-core@ruby-lang.org archive (unofficial mirror)
 help / color / mirror / Atom feed
* [ruby-core:55065] [ruby-trunk - Bug #8428][Open] Date#to_time yields incorrect value for Julian dates
@ 2013-05-19 23:03 teleological (Riley Lynch)
  2019-07-17 22:03 ` [ruby-core:93823] [Ruby master Bug#8428] " merch-redmine
  0 siblings, 1 reply; 2+ messages in thread
From: teleological (Riley Lynch) @ 2013-05-19 23:03 UTC (permalink / raw
  To: ruby-core


Issue #8428 has been reported by teleological (Riley Lynch).

----------------------------------------
Bug #8428: Date#to_time yields incorrect value for Julian dates
https://bugs.ruby-lang.org/issues/8428

Author: teleological (Riley Lynch)
Status: Open
Priority: Normal
Assignee: 
Category: ext
Target version: 
ruby -v: ruby 1.9.3p429 (2013-05-15 revision 40747) [x86_64-darwin12.3.0]
Backport: 1.9.3: UNKNOWN, 2.0.0: UNKNOWN


=begin
Date instances with Julian day values that precede the calendar reform start day (i.e. #julian? == true), return Time objects which do not correspond to the chronological Julian day which the Date instances represent.

  d = Date.new(1582, 10, 15)
  d.gregorian?              # => true
  d = d.jd                  # => 2299161
  d.to_time.to_date.jd      # => 2299161 (OK)

  d = Date.new(1582, 10, 4)
  d.gregorian?              # => false
  d = d.jd                  # => 2299160
  d.to_time.to_date.jd      # => 2299150 (!)

An equivalent Date object using a fixed Gregorian calendar does not exhibit the same behavior:

  d = Date.new(1582, 10, 14, Date::GREGORIAN)
  d == Date.new(1582, 10, 4) # => true
  d = d.jd                   # => 2299160
  d.to_time.to_date.jd       # => 2299160 (OK)

Since the documentation for Date#to_time is not detailed about the expected behavior of Date#to_time ("returns a Time object which denotes self"), and since no rubyspec has been defined for this method yet, I realize that it is contentious to describe this behavior as a bug, so I'd like to put a few arguments forward that the current behavior is not correct or desirable.

(1) Since 1.9, Time#to_date always uses the Gregorian year, month and day indicated by a Time instance to construct a Date instance. This is a correction from Ruby 1.8's private Time#to_date, which used the calendar representation of the date according to the default reform day.

(2) The value of a Time instance is an instant defined as an offset from the Unix epoch. The instant falls within a particular chronological Julian day beginning at UTC-offset midnight. Date#to_time should respect the relationship between the chronological Julian day value of the Date instance and the Unix epoch offset value of the Time instance: If the value of the Time instance doesn't fall within the same chronological Julian day as is represented by the Date instance, the conversion is incorrect.

(3) Although an instance of Time is capable of representing the beginning of any chronological Julian day, it is not capable or representing a date in the Julian calendar. Since an instance of Time masquerading as a Julian date such as the current result of (({Date.new(1582, 10, 4).to_time})) actually represents a different value, its value and any calculations based on its value are likely to mislead, as are comparisons with other instances of Time.

The following patch to (({ext/date/date_core.c})) would make Date#to_time work uniformly for Gregorian and Julian dates:

  @@ -8604,12 +8604,21 @@ time_to_datetime(VALUE self)
   static VALUE
   date_to_time(VALUE self)
   {
  -    get_d1(self);
  -
  -    return f_local3(rb_cTime,
  -                   m_real_year(dat),
  -                   INT2FIX(m_mon(dat)),
  -                   INT2FIX(m_mday(dat)));
  +    get_d1a(self);
  +    if (m_julian_p(adat)) {
  +      VALUE tmp = d_lite_gregorian(self);
  +      get_d1b(tmp);
  +      return f_local3(rb_cTime,
  +        m_real_year(bdat),
  +        INT2FIX(m_mon(bdat)),
  +        INT2FIX(m_mday(bdat)));
  +    }
  +    else {
  +      return f_local3(rb_cTime,
  +        m_real_year(adat),
  +        INT2FIX(m_mon(adat)),
  +        INT2FIX(m_mday(adat)));
  +    }
   }

If this proposal is too contentious for a bug report, I would be glad to reintroduce it in a mailing list or in whatever forum is deemed more appropriate for discussing a change like this. Thank you for your consideration!
=end


-- 
http://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 2+ messages in thread

* [ruby-core:93823] [Ruby master Bug#8428] Date#to_time yields incorrect value for Julian dates
  2013-05-19 23:03 [ruby-core:55065] [ruby-trunk - Bug #8428][Open] Date#to_time yields incorrect value for Julian dates teleological (Riley Lynch)
@ 2019-07-17 22:03 ` merch-redmine
  0 siblings, 0 replies; 2+ messages in thread
From: merch-redmine @ 2019-07-17 22:03 UTC (permalink / raw
  To: ruby-core

Issue #8428 has been updated by jeremyevans0 (Jeremy Evans).

Backport deleted (1.9.3: UNKNOWN, 2.0.0: UNKNOWN)

I agree this is a bug that we should fix, and converting from julian to gregorian before converting to Time makes sense.  It does have the downside of the Time object having a different mday value than the Date object, but without adding calendar support to Time, I don't think that is fixable.

I've added a pull request to implement this (https://github.com/ruby/date/pull/8), which uses a similar approach to the patch provided.

----------------------------------------
Bug #8428: Date#to_time yields incorrect value for Julian dates
https://bugs.ruby-lang.org/issues/8428#change-79689

* Author: teleological (Riley Lynch)
* Status: Open
* Priority: Normal
* Assignee: 
* Target version: 
* ruby -v: ruby 1.9.3p429 (2013-05-15 revision 40747) [x86_64-darwin12.3.0]
* Backport: 
----------------------------------------
=begin
Date instances with Julian day values that precede the calendar reform start day (i.e. #julian? == true), return Time objects which do not correspond to the chronological Julian day which the Date instances represent.

  d = Date.new(1582, 10, 15)
  d.gregorian?              # => true
  d = d.jd                  # => 2299161
  d.to_time.to_date.jd      # => 2299161 (OK)

  d = Date.new(1582, 10, 4)
  d.gregorian?              # => false
  d = d.jd                  # => 2299160
  d.to_time.to_date.jd      # => 2299150 (!)

An equivalent Date object using a fixed Gregorian calendar does not exhibit the same behavior:

  d = Date.new(1582, 10, 14, Date::GREGORIAN)
  d == Date.new(1582, 10, 4) # => true
  d = d.jd                   # => 2299160
  d.to_time.to_date.jd       # => 2299160 (OK)

Since the documentation for Date#to_time is not detailed about the expected behavior of Date#to_time ("returns a Time object which denotes self"), and since no rubyspec has been defined for this method yet, I realize that it is contentious to describe this behavior as a bug, so I'd like to put a few arguments forward that the current behavior is not correct or desirable.

(1) Since 1.9, Time#to_date always uses the Gregorian year, month and day indicated by a Time instance to construct a Date instance. This is a correction from Ruby 1.8's private Time#to_date, which used the calendar representation of the date according to the default reform day.

(2) The value of a Time instance is an instant defined as an offset from the Unix epoch. The instant falls within a particular chronological Julian day beginning at UTC-offset midnight. Date#to_time should respect the relationship between the chronological Julian day value of the Date instance and the Unix epoch offset value of the Time instance: If the value of the Time instance doesn't fall within the same chronological Julian day as is represented by the Date instance, the conversion is incorrect.

(3) Although an instance of Time is capable of representing the beginning of any chronological Julian day, it is not capable or representing a date in the Julian calendar. Since an instance of Time masquerading as a Julian date such as the current result of (({Date.new(1582, 10, 4).to_time})) actually represents a different value, its value and any calculations based on its value are likely to mislead, as are comparisons with other instances of Time.

The following patch to (({ext/date/date_core.c})) would make Date#to_time work uniformly for Gregorian and Julian dates:

  @@ -8604,12 +8604,21 @@ time_to_datetime(VALUE self)
   static VALUE
   date_to_time(VALUE self)
   {
  -    get_d1(self);
  -
  -    return f_local3(rb_cTime,
  -                   m_real_year(dat),
  -                   INT2FIX(m_mon(dat)),
  -                   INT2FIX(m_mday(dat)));
  +    get_d1a(self);
  +    if (m_julian_p(adat)) {
  +      VALUE tmp = d_lite_gregorian(self);
  +      get_d1b(tmp);
  +      return f_local3(rb_cTime,
  +        m_real_year(bdat),
  +        INT2FIX(m_mon(bdat)),
  +        INT2FIX(m_mday(bdat)));
  +    }
  +    else {
  +      return f_local3(rb_cTime,
  +        m_real_year(adat),
  +        INT2FIX(m_mon(adat)),
  +        INT2FIX(m_mday(adat)));
  +    }
   }

If this proposal is too contentious for a bug report, I would be glad to reintroduce it in a mailing list or in whatever forum is deemed more appropriate for discussing a change like this. Thank you for your consideration!
=end



-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2019-07-17 22:03 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-05-19 23:03 [ruby-core:55065] [ruby-trunk - Bug #8428][Open] Date#to_time yields incorrect value for Julian dates teleological (Riley Lynch)
2019-07-17 22:03 ` [ruby-core:93823] [Ruby master Bug#8428] " merch-redmine

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).