{-# LANGUAGE DeriveLift #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
module Data.Time.Clock.Duration.Types
(
AbsoluteDuration (..)
, RelativeDuration (..)
, Time (..)
) where
import Data.Int (Int8, Int16, Int32, Int64)
import Data.Fixed (E6, E12, Fixed, HasResolution (resolution))
import Data.Proxy (Proxy (Proxy))
import Data.Ratio (Ratio)
import Data.Time.Clock (DiffTime, NominalDiffTime, picosecondsToDiffTime)
import Foreign.C.Types (CSUSeconds (CSUSeconds), CUSeconds (CUSeconds))
import Language.Haskell.TH.Syntax (Lift)
class AbsoluteDuration a where
toAbsoluteDuration :: Time -> a
instance AbsoluteDuration DiffTime where
toAbsoluteDuration :: Time -> DiffTime
toAbsoluteDuration = Integer -> DiffTime
picosecondsToDiffTime (Integer -> DiffTime) -> (Time -> Integer) -> Time -> DiffTime
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Rational -> Integer
forall a b. (RealFrac a, Integral b) => a -> b
round (Rational -> Integer) -> (Time -> Rational) -> Time -> Integer
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Rational -> Rational
inPsScale (Rational -> Rational) -> (Time -> Rational) -> Time -> Rational
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Time -> Rational
toSeconds
instance AbsoluteDuration NominalDiffTime where
toAbsoluteDuration :: Time -> NominalDiffTime
toAbsoluteDuration = DiffTime -> NominalDiffTime
forall a b. (Real a, Fractional b) => a -> b
realToFrac (DiffTime -> NominalDiffTime)
-> (Time -> DiffTime) -> Time -> NominalDiffTime
forall b c a. (b -> c) -> (a -> b) -> a -> c
. AbsoluteDuration DiffTime => Time -> DiffTime
forall a. AbsoluteDuration a => Time -> a
toAbsoluteDuration @DiffTime
instance AbsoluteDuration CUSeconds where
toAbsoluteDuration :: Time -> CUSeconds
toAbsoluteDuration = Word32 -> CUSeconds
CUSeconds (Word32 -> CUSeconds) -> (Time -> Word32) -> Time -> CUSeconds
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Rational -> Word32
forall a b. (RealFrac a, Integral b) => a -> b
round (Rational -> Word32) -> (Time -> Rational) -> Time -> Word32
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Rational -> Rational
inµsScale (Rational -> Rational) -> (Time -> Rational) -> Time -> Rational
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Time -> Rational
toSeconds
instance AbsoluteDuration CSUSeconds where
toAbsoluteDuration :: Time -> CSUSeconds
toAbsoluteDuration = Int64 -> CSUSeconds
CSUSeconds (Int64 -> CSUSeconds) -> (Time -> Int64) -> Time -> CSUSeconds
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Rational -> Int64
forall a b. (RealFrac a, Integral b) => a -> b
round (Rational -> Int64) -> (Time -> Rational) -> Time -> Int64
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Rational -> Rational
inµsScale (Rational -> Rational) -> (Time -> Rational) -> Time -> Rational
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Time -> Rational
toSeconds
class RelativeDuration a where
toRelativeDuration :: HasResolution r => Proxy r -> Time -> a
instance RelativeDuration Int where
toRelativeDuration :: Proxy r -> Time -> Int
toRelativeDuration Proxy r
proxy = Rational -> Int
forall a b. (RealFrac a, Integral b) => a -> b
round (Rational -> Int) -> (Time -> Rational) -> Time -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Proxy r -> Rational -> Rational
forall r. HasResolution r => Proxy r -> Rational -> Rational
convertScale Proxy r
proxy (Rational -> Rational) -> (Time -> Rational) -> Time -> Rational
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Time -> Rational
toSeconds
instance RelativeDuration Int8 where
toRelativeDuration :: Proxy r -> Time -> Int8
toRelativeDuration Proxy r
proxy = Rational -> Int8
forall a b. (RealFrac a, Integral b) => a -> b
round (Rational -> Int8) -> (Time -> Rational) -> Time -> Int8
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Proxy r -> Rational -> Rational
forall r. HasResolution r => Proxy r -> Rational -> Rational
convertScale Proxy r
proxy (Rational -> Rational) -> (Time -> Rational) -> Time -> Rational
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Time -> Rational
toSeconds
instance RelativeDuration Int16 where
toRelativeDuration :: Proxy r -> Time -> Int16
toRelativeDuration Proxy r
proxy = Rational -> Int16
forall a b. (RealFrac a, Integral b) => a -> b
round (Rational -> Int16) -> (Time -> Rational) -> Time -> Int16
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Proxy r -> Rational -> Rational
forall r. HasResolution r => Proxy r -> Rational -> Rational
convertScale Proxy r
proxy (Rational -> Rational) -> (Time -> Rational) -> Time -> Rational
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Time -> Rational
toSeconds
instance RelativeDuration Int32 where
toRelativeDuration :: Proxy r -> Time -> Int32
toRelativeDuration Proxy r
proxy = Rational -> Int32
forall a b. (RealFrac a, Integral b) => a -> b
round (Rational -> Int32) -> (Time -> Rational) -> Time -> Int32
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Proxy r -> Rational -> Rational
forall r. HasResolution r => Proxy r -> Rational -> Rational
convertScale Proxy r
proxy (Rational -> Rational) -> (Time -> Rational) -> Time -> Rational
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Time -> Rational
toSeconds
instance RelativeDuration Int64 where
toRelativeDuration :: Proxy r -> Time -> Int64
toRelativeDuration Proxy r
proxy = Rational -> Int64
forall a b. (RealFrac a, Integral b) => a -> b
round (Rational -> Int64) -> (Time -> Rational) -> Time -> Int64
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Proxy r -> Rational -> Rational
forall r. HasResolution r => Proxy r -> Rational -> Rational
convertScale Proxy r
proxy (Rational -> Rational) -> (Time -> Rational) -> Time -> Rational
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Time -> Rational
toSeconds
instance RelativeDuration Integer where
toRelativeDuration :: Proxy r -> Time -> Integer
toRelativeDuration Proxy r
proxy = Rational -> Integer
forall a b. (RealFrac a, Integral b) => a -> b
round (Rational -> Integer) -> (Time -> Rational) -> Time -> Integer
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Proxy r -> Rational -> Rational
forall r. HasResolution r => Proxy r -> Rational -> Rational
convertScale Proxy r
proxy (Rational -> Rational) -> (Time -> Rational) -> Time -> Rational
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Time -> Rational
toSeconds
instance HasResolution a => RelativeDuration (Fixed a) where
toRelativeDuration :: Proxy r -> Time -> Fixed a
toRelativeDuration Proxy r
proxy = Rational -> Fixed a
forall a b. (Real a, Fractional b) => a -> b
realToFrac (Rational -> Fixed a) -> (Time -> Rational) -> Time -> Fixed a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Proxy r -> Rational -> Rational
forall r. HasResolution r => Proxy r -> Rational -> Rational
convertScale Proxy r
proxy (Rational -> Rational) -> (Time -> Rational) -> Time -> Rational
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Time -> Rational
toSeconds
instance Integral a => RelativeDuration (Ratio a) where
toRelativeDuration :: Proxy r -> Time -> Ratio a
toRelativeDuration Proxy r
proxy = Rational -> Ratio a
forall a b. (Real a, Fractional b) => a -> b
realToFrac (Rational -> Ratio a) -> (Time -> Rational) -> Time -> Ratio a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Proxy r -> Rational -> Rational
forall r. HasResolution r => Proxy r -> Rational -> Rational
convertScale Proxy r
proxy (Rational -> Rational) -> (Time -> Rational) -> Time -> Rational
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Time -> Rational
toSeconds
instance RelativeDuration Float where
toRelativeDuration :: Proxy r -> Time -> Float
toRelativeDuration Proxy r
proxy = Rational -> Float
forall a b. (Real a, Fractional b) => a -> b
realToFrac (Rational -> Float) -> (Time -> Rational) -> Time -> Float
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Proxy r -> Rational -> Rational
forall r. HasResolution r => Proxy r -> Rational -> Rational
convertScale Proxy r
proxy (Rational -> Rational) -> (Time -> Rational) -> Time -> Rational
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Time -> Rational
toSeconds
instance RelativeDuration Double where
toRelativeDuration :: Proxy r -> Time -> Double
toRelativeDuration Proxy r
proxy = Rational -> Double
forall a b. (Real a, Fractional b) => a -> b
realToFrac (Rational -> Double) -> (Time -> Rational) -> Time -> Double
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Proxy r -> Rational -> Rational
forall r. HasResolution r => Proxy r -> Rational -> Rational
convertScale Proxy r
proxy (Rational -> Rational) -> (Time -> Rational) -> Time -> Rational
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Time -> Rational
toSeconds
data Time
= Picosec Rational
| Nanosec Rational
| Microsec Rational
| Millisec Rational
| Second Rational
| Minute Rational
| Hour Rational
| Day Rational
| Week Rational
| Year Rational
deriving (Time -> Q Exp
Time -> Q (TExp Time)
(Time -> Q Exp) -> (Time -> Q (TExp Time)) -> Lift Time
forall t. (t -> Q Exp) -> (t -> Q (TExp t)) -> Lift t
liftTyped :: Time -> Q (TExp Time)
$cliftTyped :: Time -> Q (TExp Time)
lift :: Time -> Q Exp
$clift :: Time -> Q Exp
Lift)
toSeconds :: Time -> Rational
toSeconds :: Time -> Rational
toSeconds (Picosec Rational
x) = Rational
x Rational -> Rational -> Rational
forall a. Fractional a => a -> a -> a
/ Rational
1000000000000
toSeconds (Nanosec Rational
x) = Rational
x Rational -> Rational -> Rational
forall a. Fractional a => a -> a -> a
/ Rational
1000000000
toSeconds (Microsec Rational
x) = Rational
x Rational -> Rational -> Rational
forall a. Fractional a => a -> a -> a
/ Rational
1000000
toSeconds (Millisec Rational
x) = Rational
x Rational -> Rational -> Rational
forall a. Fractional a => a -> a -> a
/ Rational
1000
toSeconds (Second Rational
x) = Rational
x
toSeconds (Minute Rational
x) = Rational
x Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
* Rational
60
toSeconds (Hour Rational
x) = Rational
x Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
* Rational
60 Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
* Rational
60
toSeconds (Day Rational
x) = Rational
x Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
* Rational
60 Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
* Rational
60 Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
* Rational
24
toSeconds (Week Rational
x) = Rational
x Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
* Rational
60 Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
* Rational
60 Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
* Rational
24 Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
* Rational
7
toSeconds (Year Rational
x) = Rational
x Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
* Rational
60 Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
* Rational
60 Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
* Rational
24 Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
* Rational
365
convertScale :: forall r. (HasResolution r) => Proxy r -> Rational -> Rational
convertScale :: Proxy r -> Rational -> Rational
convertScale Proxy r
_ = (Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
* Integer -> Rational
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Fixed r -> Integer
forall k (a :: k) (p :: k -> *). HasResolution a => p a -> Integer
resolution (Fixed r
0 :: Fixed r)))
inPsScale :: Rational -> Rational
inPsScale :: Rational -> Rational
inPsScale = Proxy E12 -> Rational -> Rational
forall r. HasResolution r => Proxy r -> Rational -> Rational
convertScale (Proxy E12
forall k (t :: k). Proxy t
Proxy :: Proxy E12)
inµsScale :: Rational -> Rational
inµsScale :: Rational -> Rational
inµsScale = Proxy E6 -> Rational -> Rational
forall r. HasResolution r => Proxy r -> Rational -> Rational
convertScale (Proxy E6
forall k (t :: k). Proxy t
Proxy :: Proxy E6)