git.iko.soy/typeable/postgresql-simple
on master help sign in
Rounding doesn't belong here

The problem is that rounding up can create the need for some complicated date-time manipulations. So instead we send all the digits we have to PostgreSQL.

commit19e095766f84548bc9674f51f6714b9ebacd72ca authorLeon P Smith <leon@melding-monads.com> dateSat 2 Jun 2012, 21:57 (14 years ago) parenta6638dd
1 file changed+38−38
src/Database/PostgreSQL/Simple/Time/Implementation.hs+38−38
src/Database/PostgreSQL/Simple/Time/Implementation.hs+38−38
@@ -184,11 +184,7 @@ dayToBuilder (toGregorian -> (y,m,d)) = do
184184
185185timeOfDayToBuilder :: TimeOfDay -> Builder
186186timeOfDayToBuilder (TimeOfDay h m s) = do
187− pad2 h ++ fromChar ':' ++ pad2 m ++ fromChar ':' ++ showSec s
188− where
189− showSec s = case toMicroseconds s of
190− (s, 0) -> pad2 s
191− (s,us) -> pad2 s ++ fromChar '.' ++ showMicroseconds us
187+ pad2 h ++ fromChar ':' ++ pad2 m ++ fromChar ':' ++ showSeconds s
192188
193189timeZoneToBuilder :: TimeZone -> Builder
194190timeZoneToBuilder tz
@@ -231,34 +227,38 @@ localTimestampToBuilder = unboundedToBuilder localTimeToBuilder
231227dateToBuilder :: Date -> Builder
232228dateToBuilder = unboundedToBuilder dayToBuilder
233229
234−toMicroseconds :: Pico -> (Int,Int)
235−-- A kludge to work around the fact that Data.Fixed isn't very fast and doesn't
236−-- give me access to the MkFixed constructor.
237−toMicroseconds p = let (x,y) = (unsafeCoerce p :: Integer)
238− `quotRem` 1000000000000
239− (y',r) = y `quotRem` 1000000
240− y'' = case compare r 500000 of
241− LT -> y'
242− EQ | even y' -> y'
243− _ -> y' + 1
244− in ( fromIntegral x, fromIntegral y'' )
245−
246−-- Assumes the input is within the range [0..999999]
247−showMicroseconds :: Int -> Builder
248−showMicroseconds us =
249− case us `quotRem` 1000 of
250− (ms, 0) -> case ms `quotRem` 100 of
251− (a, 0) -> p a
252− (a,ms) -> case ms `quotRem` 10 of
253− (b,0) -> p a ++ p b
254− (b,c) -> p a ++ p b ++ p c
255− (ms,us) -> case ms `quotRem` 100 of
256− (a,ms) -> case ms `quotRem` 10 of
257− (b ,c) -> case us `quotRem` 100 of
258− (d, 0) -> p a ++ p b ++ p c ++ p d
259− (d,us) -> case us `quotRem` 10 of
260− (e , 0) -> p a ++ p b ++ p c ++ p d ++ p e
261− (e , f) -> p a ++ p b ++ p c ++ p d ++ p e ++ p f
230+showSeconds :: Pico -> Builder
231+showSeconds xyz
232+ | yz == 0 = pad2 x
233+ | z == 0 = pad2 x ++ fromChar '.' ++ showD6 y
234+ | otherwise = pad2 x ++ fromChar '.' ++ pad6 y ++ showD6 z
235+ where
236+ -- A kludge to work around the fact that Data.Fixed isn't very fast and
237+ -- doesn't give me access to the MkFixed constructor.
238+ (x_,yz) = (unsafeCoerce xyz :: Integer) `quotRem` 1000000000000
239+ x = fromIntegral x_ :: Int
240+ (fromIntegral -> y, fromIntegral -> z) = yz `quotRem` 1000000
241+
242+pad6 :: Int -> Builder
243+pad6 xy = let (x,y) = xy `quotRem` 1000
244+ in pad3 x ++ pad3 y
245+
246+showD6 :: Int -> Builder
247+showD6 xy = case xy `quotRem` 1000 of
248+ (x,0) -> showD3 x
249+ (x,y) -> pad3 x ++ showD3 y
250+
251+pad3 :: Int -> Builder
252+pad3 abc = let (ab,c) = abc `quotRem` 10
253+ (a,b) = ab `quotRem` 10
254+ in p a ++ p b ++ p c
255+
256+showD3 :: Int -> Builder
257+showD3 abc = case abc `quotRem` 100 of
258+ (a, 0) -> p a
259+ (a,bc) -> case bc `quotRem` 10 of
260+ (b,0) -> p a ++ p b
261+ (b,c) -> p a ++ p b ++ p c
262262
263263-- | p assumes its input is in the range [0..9]
264264p :: Integral n => n -> Builder
@@ -272,9 +272,9 @@ pad2 n = let (a,b) = n `quotRem` 10 in p a ++ p b
272272
273273-- | pad4 assumes its input is positive
274274pad4 :: (Integral n, Show n) => n -> Builder
275−pad4 n | n >= 10000 = integral n
276− | otherwise = p a ++ p b ++ p c ++ p d
277− where (ab,cd) = n `quotRem` 100
278− (a,b) = ab `quotRem` 10
279− (c,d) = cd `quotRem` 10
275+pad4 abcd | abcd >= 10000 = integral abcd
276+ | otherwise = p a ++ p b ++ p c ++ p d
277+ where (ab,cd) = abcd `quotRem` 100
278+ (a,b) = ab `quotRem` 10
279+ (c,d) = cd `quotRem` 10
280280{-# INLINE pad4 #-}