Project

General

Profile

Actions

Bug #18946

closed

Time#to_date returns incorrect date

Added by kei-p (Keisuke Ishizawa) over 2 years ago. Updated over 2 years ago.

Status:
Closed
Assignee:
-
Target version:
-
[ruby-dev:51185]

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) over 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) over 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) over 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) over 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.

Actions #5

Updated by nobu (Nobuyoshi Nakada) over 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) over 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.

Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0Like0