Bug #18946
closedTime#to_date returns incorrect date
Description
Time#to_date returns incorrect date.
Actual Behavior:
Time.local(1499, 12, 27).to_date
=> #<Date: 1499-12-18 ((2268919j,0s,0n),+0s,2299161j)>
Expected Behavior:
Time.local(1499, 12, 27).to_date
=> #<Date: 1499-12-27 ...>
Updated by duerst (Martin Dürst) about 2 years ago
This may be due to the Gregorian calendar reform (see https://en.wikipedia.org/wiki/Gregorian_calendar#Gregorian_reform, which says: "Julian Thursday, 4 October 1582, being followed by Gregorian Friday, 15 October").
Time seems to use a proleptic Gregorian calendar (the Gregorian calendar extended to before the Gregorian reform, see https://en.wikipedia.org/wiki/Proleptic_Gregorian_calendar) while Date seems to be using the Julian calendar before the 'official' reform date. Please note that the reform didn't get applied at that date everywhere; different parts of the globe changed at different times, and some churches still use the old calendar.
Time.local(1582,10,14).to_date
=> #<Date: 1582-10-04 ((2299160j,0s,0n),+0s,2299161j)>
Time.local(1582,10,15).to_date
=> #<Date: 1582-10-15 ((2299161j,0s,0n),+0s,2299161j)>
Also, please compare:
Time.local(1500,3,1).to_date
=> #<Date: 1500-02-20 ((2268983j,0s,0n),+0s,2299161j)>
Time.local(1500,2,29).to_date
=> #<Date: 1500-02-20 ((2268983j,0s,0n),+0s,2299161j)>
(in Time, there's no February 29 in 1500, because it's proleptic)
with
Time.local(1500,3,9).to_date
=> #<Date: 1500-02-28 ((2268991j,0s,0n),+0s,2299161j)>
Time.local(1500,3,10).to_date
=> #<Date: 1500-02-29 ((2268992j,0s,0n),+0s,2299161j)>
Time.local(1500,3,11).to_date
=> #<Date: 1500-03-01 ((2268993j,0s,0n),+0s,2299161j)>
In Date, there is a February 29 in 1500, because it's Julian.
See also ri Date
. It may be a good idea to add a note to the documentation for Time, to say that it uses the proleptic Gregorian calendar, and this is different from Date.
Please note that dates are relatively easy if the date is close to the present, but the farther you move out, the more complicated it may get.
Updated by kei-p (Keisuke Ishizawa) about 2 years ago
Time seems to use a proleptic Gregorian calendar (the Gregorian calendar extended to before the Gregorian reform, see https://en.wikipedia.org/wiki/Proleptic_Gregorian_calendar) while Date seems to be using the Julian calendar before the 'official' reform date.
Thanks for the detailed explanation.
I understand that this is due to the different calendars that Date and Time uses before the 'official' reform date.
Updated by jeremyevans0 (Jeremy Evans) about 2 years ago
Time#to_datetime
does not operate the same way, which seems like an undesirable inconsistency:
Time.local(1499, 12, 27).to_datetime
=> #<DateTime: 1499-12-27T00:00:00-07:52 ((2268928j,28378s,0n),-28378s,2299161j)>
Time.local(1499, 12, 27).to_date
=> #<Date: 1499-12-18 ((2268919j,0s,0n),+0s,2299161j)>
Updated by matz (Yukihiro Matsumoto) about 2 years ago
I checked commit history and found out that to_date has been use GREGORIAN calendar since 2011-05-31 and to_datetime preserved the old DEFAULT_SG (ITALY). I assume this is a mistake and both should use GREGORIAN (ext/date/date_core.c:8647).
Matz.
Updated by nobu (Nobuyoshi Nakada) about 2 years ago
- Status changed from Open to Closed
Applied in changeset git|e0dfa5967e7063da8b65dc3c062ef4652e246e34.
[Bug #18946] Use Gregorian dates to test
Updated by nobu (Nobuyoshi Nakada) about 2 years ago
Fixed this issue itself, but turned out Psych had a related issue.
The YAML spec doesn’t considered the calendar systems.
Although I reported, as it hasn’t been concluded yet, the failing test is excluded now at git|79fdf9712dea4943a15c4ef34348b1a159b62f4a.