Change negative days by 1 to account for missing year zero

This commit is contained in:
2023-10-03 20:19:40 +02:00
parent 94401a2753
commit 9c93d3a42b
3 changed files with 22 additions and 10 deletions
+11 -4
View File
@@ -25,6 +25,7 @@ import Data.Time
, fromGregorian
, picosecondsToDiffTime
, timeToTimeOfDay
, toGregorian
)
import Data.Text (Text)
import Data.Word (Word32, Word64)
@@ -129,13 +130,19 @@ instance FromField Bool where
postgresEpoch :: Day
postgresEpoch = fromGregorian 2000 1 1
fromPostgresJulian :: Integer -> Day
fromPostgresJulian x
| year <= 0 = fromGregorian (year - 1) month dayOfMonth
| otherwise = day
where
day = addDays (fromIntegral x) postgresEpoch
(year, month, dayOfMonth) = toGregorian day
-- | See https://www.postgresql.org/docs/current/datatype-datetime.html.
-- Relevant as well: https://git.postgresql.org/gitweb/?p=postgresql.git;a=blob;f=src/backend/utils/adt/datetime.c;h=267dfd37b2e8b9bc63797c69b9ca2e45e6bfde61;hb=HEAD#l267.
instance FromField Day where
validOid Proxy = Oid.date
parseField = fromJulianDay <$> intParser @Int32
where
fromJulianDay x = addDays (fromIntegral x) postgresEpoch
parseField = fromPostgresJulian . fromIntegral <$> intParser @Int32
-- | See https://www.postgresql.org/docs/current/datatype-datetime.html.
-- Binary format: https://git.postgresql.org/gitweb/?p=postgresql.git;a=blob;f=src/backend/utils/adt/date.c;h=ae0f24de2c3c54eb6d0405cdb212597c2407238e;hb=HEAD#l1542.
@@ -162,7 +169,7 @@ instance FromField UTCTime where
fromPostgresTimestamp ts =
let
(days, microseconds) = ts `divMod` (86400 * 1000000)
day = addDays (fromIntegral days) postgresEpoch
day = fromPostgresJulian $ fromIntegral days
time = picosecondsToDiffTime $ fromIntegral microseconds * 1000000
in
UTCTime day time