Skip to content

Respect calendar type of Ruby and PostgreSQL - #736

Open
larskanis wants to merge 1 commit into
ged:masterfrom
larskanis:fix-725
Open

Respect calendar type of Ruby and PostgreSQL#736
larskanis wants to merge 1 commit into
ged:masterfrom
larskanis:fix-725

Conversation

@larskanis

Copy link
Copy Markdown
Collaborator

PostgreSQL uses gregorian calendar for all dates.
It is described here:
https://www.postgresql.org/docs/10/datetime-units-history.html

Ruby treats dates before 1852-10-05 as julian calendar and after 1582-10-14 as gregorian calendar. It is described here:
https://docs.ruby-lang.org/en/master/language/calendars_rdoc.html#argument-start

In order to encode and decode the correct date, this PR encodes Date values send to the server as gregorian calendar. Non-gregorian dates are converted to gregorian calender before sent. The other way around, Date values decoded from the server are explicit interpret and labeled as gregorian calendar.

The new behavior could be surprising when a julian date is passed through the server and changed to gregorian like so. But it is how the two parties represent one and the same date:

  conn.exec_params("SELECT $1::date", [Date.new(1581, 5, 15)]).values
      => [[#<Date: 1581-05-25 ((2298653j,0s,0n),+0s,-Infj)>]]

So far the PG::BasicTypeMapForQueries didn't use the Date encoder. This was because it didn't have an advantage over standard to_s conversion. Now that the encoder ensures that the date is sent as gregorian calender value, it makes sense to enable it for query parameters.

Fixes #725

@larskanis
larskanis marked this pull request as ready for review August 8, 2026 20:14
PostgreSQL uses gregorian calendar for all dates.
It is described here:
  https://www.postgresql.org/docs/10/datetime-units-history.html

Ruby treats dates before 1852-10-05 as julian calendar and after 1582-10-14 as gregorian calendar.
It is described here:
  https://docs.ruby-lang.org/en/master/language/calendars_rdoc.html#argument-start

In order to encode and decode the correct date, this PR encodes Date values send to the server as gregorian calendar.
Non-gregorian dates are converted to gregorian calender before sent.
The other way around, Date values decoded from the server are explicit interpret and labeled as gregorian calendar.

The new behavior could be surprising when a julian date is passed through the server and changed to gregorian like so.
But it is how the two parties represent one and the same date:

```ruby
  conn.exec_params("SELECT $1::date", [Date.new(1581, 5, 15)]).values
      => [[#<Date: 1581-05-25 ((2298653j,0s,0n),+0s,-Infj)>]]
```

So far the PG::BasicTypeMapForQueries didn't use the Date encoder.
This was because it didn't have an advantage over standard `to_s` conversion.
Now that the encoder ensures that the date is sent as gregorian calender value, it makes sense to enable it for query parameters.

Fixes ged#725
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

PG::TextDecoder::Date fails to handle dates within the 10-day Gregorian calendar adjustment period

1 participant