PgDateText

internal object PgDateText

Translates the year between the way ISO-8601 writes it and the way PostgreSQL does.

The two disagree outside 0001..9999, and they disagree in a way no single string satisfies:

YearISO-8601 / kotlinxPostgreSQL
20242024-01-02the same
10000+10000-01-0210000-01-02
1 BC0000-01-020001-01-02 BC
2 BC-0001-01-020002-01-02 BC

ISO requires the sign on any year past four digits and PostgreSQL refuses it - it reads the sign as the start of a timezone offset, so +10000-01-02 and -0001-01-02 are both rejected outright, and so is 4713-01-02 BC's ISO spelling even though that is PostgreSQL's own minimum. ISO also has a year zero where PostgreSQL has none, which is where the off-by-one comes from: 1 BC directly precedes 1 AD.

So a payload written in ISO cannot be cast back to a date at all past year 9999 or before year 1. This writes PostgreSQL's form instead, and reads either back - a payload built in SQL, or one written before this existed, still decodes.

None of this widens what a column holds: date reaches 4713 BC to 5874897 AD and timestamp 294276 AD, and a value outside that is out of range whichever way it is spelled.

Functions

Link copied to clipboard
fun fromIso(iso: String): String

Rewrites the leading year of an ISO-8601 date or timestamp into PostgreSQL's spelling.

Link copied to clipboard
fun toIso(text: String): String

Rewrites a year in PostgreSQL's spelling back into the one kotlinx.datetime parses.