@@ -189,28 +189,43 @@ timeOfDay t = timeOfDay64 (toTimeOfDay64 t)
189{-# INLINE timeOfDay #-}
189{-# INLINE timeOfDay #-}
191timeOfDay64 :: TimeOfDay64 -> Builder
191timeOfDay64 :: TimeOfDay64 -> Builder
192−timeOfDay64 (TOD h m s0)
192+timeOfDay64 (TOD h m s)
193− | frac < mu = hhmmss -- omit trailing milliseconds if zero
193+ | frac == 0 = hhmmss -- omit subseconds if 0
194− | otherwise = hhmmss <> BP.primBounded (ascii4 ('.',(a,(b,c)))) ()
194+ | otherwise = hhmmss <> BP.primBounded showFrac frac
196 hhmmss = BP.primBounded (ascii8 (hh,(hl,(':',(mh,(ml,(':',(sh,sl)))))))) ()
196 hhmmss = BP.primBounded (ascii8 (hh,(hl,(':',(mh,(ml,(':',(sh,sl)))))))) ()
197 !(T hh hl) = twoDigits h
197 !(T hh hl) = twoDigits h
198 !(T mh ml) = twoDigits m
198 !(T mh ml) = twoDigits m
199 !(T sh sl) = twoDigits (fromIntegral real)
199 !(T sh sl) = twoDigits (fromIntegral real)
200 (real,frac) = s `quotRem` pico
200 (real,frac) = s `quotRem` pico
201− -- Round fractional milliseconds to render more accurately. We
201+
202− -- give up when there are leap seconds in play or there might be a
202+ showFrac = (\x -> ('.', x)) >$< (BP.liftFixedToBounded BP.char7 >*< trunc12)
203− -- need for carry propagation.
203+
204− s | s0 >= 59999000000000 = s0
204+ trunc12 =
205− | s0 `rem` mu < nu = s0
205+ (`quotRem` micro) >$<
206− | otherwise = s0 + mu
206+ BP.condB (\(_,y) -> y == 0) (fst >$< trunc6) (digits6 >*< trunc6)
207− tenths = fromIntegral (frac `quot` mu)
207+
208+ digits6 = ((`quotRem` milli) . fromIntegral) >$< (digits3 >*< digits3)
211+ ((`quotRem` milli) . fromIntegral) >$<
212+ BP.condB (\(_,y) -> y == 0) (fst >$< trunc3) (digits3 >*< trunc3)
214+ digits3 = ((`quotRem` 10) >$< (digits2 >*< digits1))
216+ digits2 = (`quotRem` 10) >$< (digits1 >*< digits1)
218+ digits1 = BP.liftFixedToBounded (digit >$< BP.char7)
220+ trunc3 = BP.condB (== 0) BP.emptyB $
221+ ((`quotRem` 100) >$< (digits1 >*< trunc2))
222+ trunc2 = BP.condB (== 0) BP.emptyB $
223+ ((`quotRem` 10) >$< (digits1 >*< trunc1))
224+ trunc1 = BP.condB (== 0) BP.emptyB digits1
208− pico = 1000000000000 -- 1 second in picoseconds
226+ pico = 1000000000000 -- number of picoseconds in 1 second
209− mu = 1000000000 -- 100 microseconds
227+ micro = 1000000 -- number of microseconds in 1 second
210− nu = 500000000
228+ milli = 1000 -- number of milliseconds in 1 second
211− !(T a b) = twoDigits ab
212− (ab,cc) = tenths `quotRem` 10
214{-# INLINE timeOfDay64 #-}
229{-# INLINE timeOfDay64 #-}
216timeZone :: TimeZone -> Builder
231timeZone :: TimeZone -> Builder