git.iko.soy/typeable/postgresql-simple
on master help sign in
Improve Timezone Handling
119f516Leon P Smith
src/Database/PostgreSQL/Simple/Time/Implementation.hs+6−4
@@ -136,10 +136,12 @@ getLocalTimestamp = getUnbounded getLocalTime
136
136
137getTimeZone :: A.Parser TimeZone
137getTimeZone :: A.Parser TimeZone
138getTimeZone = do
138getTimeZone = do
139− sign <- A.satisfy (\c -> c == '+' || c == '-')
139+ sign <- A.satisfy (\c -> c == '+' || c == '-')
140− offset <- digits "timezone"
140+ hours <- digits "timezone"
141+ mins <- (A.char ':' *> digits "timezone minutes") <|> pure 0
142+ let !absset = 60 * hours + mins
141− let !minutes = 60 * if sign == '+' then offset else -offset
143+ !offset = if sign == '+' then absset else -absset
142− return $! minutesToTimeZone minutes
144+ return $! minutesToTimeZone offset
143
145
144getZonedTime :: A.Parser ZonedTime
146getZonedTime :: A.Parser ZonedTime
145getZonedTime = ZonedTime <$> getLocalTime <*> getTimeZone
147getZonedTime = ZonedTime <$> getLocalTime <*> getTimeZone
test/Time.hs+5−1
@@ -39,6 +39,10 @@ testTime env@TestEnv{..} = TestCase $ do
39 checkRoundTrips env
39 checkRoundTrips env
40 execute_ conn "SET timezone TO 'Asia/Tokyo'"
40 execute_ conn "SET timezone TO 'Asia/Tokyo'"
41 checkRoundTrips env
41 checkRoundTrips env
42+ execute_ conn "SET timezone TO 'Asia/Kathmandu'"
43+ checkRoundTrips env
44+ execute_ conn "SET timezone TO 'America/St_Johns'"
45+ checkRoundTrips env
42
46
43initializeTable :: TestEnv -> IO ()
47initializeTable :: TestEnv -> IO ()
44initializeTable TestEnv{..} = withTransaction conn $ do
48initializeTable TestEnv{..} = withTransaction conn $ do
@@ -48,7 +52,7 @@ initializeTable TestEnv{..} = withTransaction conn $ do
48 let pop :: ByteString -> Double -> IO () = \x y ->
52 let pop :: ByteString -> Double -> IO () = \x y ->
49 replicateM_ numTests $ execute conn
53 replicateM_ numTests $ execute conn
50 [sql| INSERT INTO testtime (y) VALUES
54 [sql| INSERT INTO testtime (y) VALUES
51− ('1900-01-01 00:00:00+00'::timestamptz
55+ ('1936-01-01 00:00:00+00'::timestamptz
52 + ?::interval * ROUND(RANDOM() * ?)) |] (x,y)
56 + ?::interval * ROUND(RANDOM() * ?)) |] (x,y)
53 pop "1 microsecond" 6.3113904e15
57 pop "1 microsecond" 6.3113904e15
54 pop "10 microseconds" 6.3113904e14
58 pop "10 microseconds" 6.3113904e14