on master help sign in
Grand unification of time-related functions
commit94a4edc087aa33de9881bf9aff90737d7ea1e141 authorBryan O'Sullivan <bos@serpentine.com> dateTue 21 Jul 2015, 21:01 (11 years ago) parent11b83ed
6 files changed+63−45
Data/Aeson/Encode/Builder.hs+2−17 Data/Aeson/Functions.hs−27 Data/Aeson/Internal/Time.hs+57 Data/Aeson/Parser/Time.hs+1−1 aeson.cabal+1 benchmarks/aeson-benchmarks.cabal+2
Data/Aeson/Encode/Builder.hs+2−17
@@ -34,20 +34,18 @@ module Data.Aeson.Encode.Builder
3434 , ascii5
3535 ) where
3636
37−import Data.Aeson.Functions (fromPico)
37+import Data.Aeson.Internal.Time
3838import Data.Aeson.Types.Internal (Encoding(..), Value(..))
3939import Data.ByteString.Builder as B
4040import Data.ByteString.Builder.Prim as BP
4141import Data.ByteString.Builder.Scientific (scientificBuilder)
4242import Data.Char (chr, ord)
43−import Data.Int (Int64)
4443import Data.Monoid ((<>))
4544import Data.Scientific (Scientific, base10Exponent, coefficient)
46−import Data.Time (DiffTime, UTCTime(..))
45+import Data.Time (UTCTime(..))
4746import Data.Time.Calendar (Day(..), toGregorian)
4847import Data.Time.LocalTime
4948import Data.Word (Word8)
50−import Unsafe.Coerce (unsafeCoerce)
5149import qualified Data.HashMap.Strict as HMS
5250import qualified Data.Text as T
5351import qualified Data.Text.Encoding as TE
@@ -225,19 +223,6 @@ utcTime :: UTCTime -> B.Builder
225223utcTime (UTCTime d s) = dayTime d (diffTimeOfDay64 s) <> B.char7 'Z'
226224{-# INLINE utcTime #-}
227225
228−data TimeOfDay64 = TOD {-# UNPACK #-} !Int
229− {-# UNPACK #-} !Int
230− {-# UNPACK #-} !Int64
231−
232−diffTimeOfDay64 :: DiffTime -> TimeOfDay64
233−diffTimeOfDay64 t = TOD (fromIntegral h) (fromIntegral m) s
234− where (h,mp) = fromIntegral pico `quotRem` 3600000000000000
235− (m,s) = mp `quotRem` 60000000000000
236− pico = unsafeCoerce t :: Integer
237−
238−toTimeOfDay64 :: TimeOfDay -> TimeOfDay64
239−toTimeOfDay64 (TimeOfDay h m s) = TOD h m (fromIntegral (fromPico s))
240−
241226localTime :: LocalTime -> Builder
242227localTime (LocalTime d t) = dayTime d (toTimeOfDay64 t)
243228{-# INLINE localTime #-}
Data/Aeson/Functions.hs−27
@@ -1,5 +1,3 @@
1−{-# LANGUAGE CPP #-}
2−
31-- |
42-- Module: Data.Aeson.Functions
53-- Copyright: (c) 2011-2015 Bryan O'Sullivan
@@ -14,37 +12,12 @@ module Data.Aeson.Functions
1412 , hashMapKey
1513 , mapKeyVal
1614 , mapKey
17− , fromPico
18− , toPico
1915 ) where
2016
2117import Data.Hashable (Hashable)
2218import qualified Data.HashMap.Strict as H
2319import qualified Data.Map as M
2420
25−#if MIN_VERSION_base(4,7,0)
26−
27−import Data.Fixed (Fixed(MkFixed), Pico)
28−
29−toPico :: Integer -> Pico
30−toPico = MkFixed
31−
32−fromPico :: Pico -> Integer
33−fromPico (MkFixed i) = i
34−
35−#else
36−
37−import Data.Fixed (Pico)
38−import Unsafe.Coerce (unsafeCoerce)
39−
40−toPico :: Integer -> Pico
41−toPico = unsafeCoerce
42−
43−fromPico :: Pico -> Integer
44−fromPico = unsafeCoerce
45−
46−#endif
47−
4821-- | Transform a 'M.Map' into a 'H.HashMap' while transforming the keys.
4922mapHashKeyVal :: (Eq k2, Hashable k2) => (k1 -> k2) -> (v1 -> v2)
5023 -> M.Map k1 v1 -> H.HashMap k2 v2
Data/Aeson/Internal/Time.hsnew file+57
@@ -0,0 +1,57 @@
1+{-# LANGUAGE CPP #-}
2+
3+-- |
4+-- Module: Data.Aeson.Internal.Time
5+-- Copyright: (c) 2015 Bryan O'Sullivan
6+-- License: Apache
7+-- Maintainer: Bryan O'Sullivan <bos@serpentine.com>
8+-- Stability: experimental
9+-- Portability: portable
10+
11+module Data.Aeson.Internal.Time
12+ (
13+ TimeOfDay64(..)
14+ , fromPico
15+ , toPico
16+ , diffTimeOfDay64
17+ , toTimeOfDay64
18+ ) where
19+
20+import Data.Fixed (Pico)
21+import Data.Int (Int64)
22+import Data.Time
23+import Unsafe.Coerce (unsafeCoerce)
24+
25+#if MIN_VERSION_base(4,7,0)
26+
27+import Data.Fixed (Fixed(MkFixed))
28+
29+toPico :: Integer -> Pico
30+toPico = MkFixed
31+
32+fromPico :: Pico -> Integer
33+fromPico (MkFixed i) = i
34+
35+#else
36+
37+toPico :: Integer -> Pico
38+toPico = unsafeCoerce
39+
40+fromPico :: Pico -> Integer
41+fromPico = unsafeCoerce
42+
43+#endif
44+
45+-- | Like TimeOfDay, but using a fixed-width integer for seconds.
46+data TimeOfDay64 = TOD {-# UNPACK #-} !Int
47+ {-# UNPACK #-} !Int
48+ {-# UNPACK #-} !Int64
49+
50+diffTimeOfDay64 :: DiffTime -> TimeOfDay64
51+diffTimeOfDay64 t = TOD (fromIntegral h) (fromIntegral m) s
52+ where (h,mp) = fromIntegral pico `quotRem` 3600000000000000
53+ (m,s) = mp `quotRem` 60000000000000
54+ pico = unsafeCoerce t :: Integer
55+
56+toTimeOfDay64 :: TimeOfDay -> TimeOfDay64
57+toTimeOfDay64 (TimeOfDay h m s) = TOD h m (fromIntegral (fromPico s))
Data/Aeson/Parser/Time.hs+1−1
@@ -23,7 +23,7 @@ module Data.Aeson.Parser.Time
2323
2424import Control.Applicative ((<$>), (<*>), (<*), (*>))
2525import Control.Monad (when, void)
26−import Data.Aeson.Functions (toPico)
26+import Data.Aeson.Internal.Time (toPico)
2727import Data.Attoparsec.Text as A
2828import Data.Bits ((.&.))
2929import Data.Char (isDigit, ord)
aeson.cabal+1
@@ -67,6 +67,7 @@ library
6767 Data.Aeson
6868 Data.Aeson.Encode
6969 Data.Aeson.Internal
70+ Data.Aeson.Internal.Time
7071 Data.Aeson.Parser
7172 Data.Aeson.Types
7273 Data.Aeson.TH
benchmarks/aeson-benchmarks.cabal+2
@@ -19,6 +19,8 @@ library
1919 Data.Aeson.Encode.Builder
2020 Data.Aeson.Encode.Functions
2121 Data.Aeson.Functions
22+ Data.Aeson.Internal
23+ Data.Aeson.Internal.Time
2224 Data.Aeson.Parser
2325 Data.Aeson.Parser.Internal
2426 Data.Aeson.Parser.Time