{-# LANGUAGE NoImplicitPrelude #-}
module Imj.Timing
(
KeyTime(..)
, addDuration
, addToSystemTime
, diffSystemTime
, diffTimeSecToMicros
, floatSecondsToDiffTime
, SystemTime(..)
, DiffTime
, getSystemTime
) where
import Imj.Prelude
import Prelude(Integer)
import Data.Int(Int64)
import Data.Time(DiffTime, diffTimeToPicoseconds,
secondsToDiffTime, picosecondsToDiffTime)
import Data.Time.Clock.System
(getSystemTime, SystemTime(..) )
addToSystemTime :: DiffTime -> SystemTime -> SystemTime
addToSystemTime diff t =
let d = diffTimeToSystemTime diff
in sumSystemTimes d t
diffSystemTime :: SystemTime
-> SystemTime
-> DiffTime
diffSystemTime (MkSystemTime s1 ns1) (MkSystemTime s2 ns2) =
let
ns1', ns2' :: Int64
ns1' = fromIntegral ns1
ns2' = fromIntegral ns2
nsDiff = ns1' - ns2'
in secondsToDiffTime (fromIntegral $ s1 - s2) +
picosecondsToDiffTime (fromIntegral nsDiff * 1000)
sumSystemTimes :: SystemTime -> SystemTime -> SystemTime
sumSystemTimes (MkSystemTime s1 ns1) (MkSystemTime s2 ns2) =
let s = s1 + s2
ns = ns1 + ns2
(addS, nanoseconds) = ns `quotRem` 1000000000
in MkSystemTime (s + fromIntegral addS) nanoseconds
picoToNano :: Integer -> Integer
picoToNano i = quot i 1000
diffTimeToSystemTime :: DiffTime -> SystemTime
diffTimeToSystemTime diff =
let nanoDiff :: Integer
nanoDiff = picoToNano $ diffTimeToPicoseconds diff
(seconds, nanoseconds) = nanoDiff `divMod` 1000000000
in MkSystemTime (fromIntegral seconds) (fromIntegral nanoseconds)
newtype KeyTime = KeyTime SystemTime deriving(Eq, Ord, Show)
diffTimeSecToMicros :: DiffTime -> Int
diffTimeSecToMicros t = floor (t * 10^(6 :: Int))
microSecondsPerSecond :: Integer
microSecondsPerSecond = 1000000
floatSecondsToDiffTime :: Float -> DiffTime
floatSecondsToDiffTime f = microsecondsToDiffTime $ floor (f*fromIntegral microSecondsPerSecond)
microsecondsToDiffTime :: Integer -> DiffTime
microsecondsToDiffTime x = fromRational (x % fromIntegral microSecondsPerSecond)
addDuration :: DiffTime -> KeyTime -> KeyTime
addDuration durationSeconds (KeyTime t) =
KeyTime $ addToSystemTime durationSeconds t