module Data.Hourglass.Epoch
(
ElapsedSince(..)
, ElapsedSinceP(..)
, Epoch(..)
, UnixEpoch(..)
, WindowsEpoch(..)
) where
import Data.Data
import Control.DeepSeq
import Data.Hourglass.Types
import Data.Hourglass.Time
newtype ElapsedSince epoch = ElapsedSince Seconds
deriving (Show,Read,Eq,Ord,Num,Data,Typeable,NFData)
data ElapsedSinceP epoch = ElapsedSinceP !(ElapsedSince epoch)
!NanoSeconds
deriving (Show,Read,Eq,Ord,Data,Typeable)
instance NFData (ElapsedSinceP e) where rnf e = e `seq` ()
instance Num (ElapsedSinceP e) where
(ElapsedSinceP e1 ns1) + (ElapsedSinceP e2 ns2) = ElapsedSinceP (e1+e2) (ns1+ns2)
(ElapsedSinceP e1 ns1) (ElapsedSinceP e2 ns2) = ElapsedSinceP (e1e2) (ns1ns2)
(ElapsedSinceP e1 ns1) * (ElapsedSinceP e2 ns2) = ElapsedSinceP (e1*e2) (ns1*ns2)
negate (ElapsedSinceP e ns) = ElapsedSinceP (negate e) ns
abs (ElapsedSinceP e ns) = ElapsedSinceP (abs e) ns
signum (ElapsedSinceP e ns) = ElapsedSinceP (signum e) ns
fromInteger i = ElapsedSinceP (ElapsedSince (fromIntegral i)) 0
class Epoch epoch where
epochName :: epoch -> String
epochDiffToUnix :: epoch -> Seconds
data UnixEpoch = UnixEpoch
deriving (Show,Eq)
instance Epoch UnixEpoch where
epochName _ = "unix"
epochDiffToUnix _ = 0
data WindowsEpoch = WindowsEpoch
deriving (Show,Eq)
instance Epoch WindowsEpoch where
epochName _ = "windows"
epochDiffToUnix _ = 11644473600
instance Epoch epoch => Timeable (ElapsedSince epoch) where
timeGetElapsedP es = ElapsedP (Elapsed e) 0
where ElapsedSince e = convertEpoch es :: ElapsedSince UnixEpoch
timeGetElapsed es = Elapsed e
where ElapsedSince e = convertEpoch es :: ElapsedSince UnixEpoch
timeGetNanoSeconds _ = 0
instance Epoch epoch => Time (ElapsedSince epoch) where
timeFromElapsedP (ElapsedP (Elapsed e) _) =
convertEpoch (ElapsedSince e :: ElapsedSince UnixEpoch)
instance Epoch epoch => Timeable (ElapsedSinceP epoch) where
timeGetElapsedP es = ElapsedP (Elapsed e) ns
where ElapsedSinceP (ElapsedSince e) ns = convertEpochP es :: ElapsedSinceP UnixEpoch
timeGetNanoSeconds (ElapsedSinceP _ ns) = ns
instance Epoch epoch => Time (ElapsedSinceP epoch) where
timeFromElapsedP (ElapsedP (Elapsed e) ns) = convertEpochP (ElapsedSinceP (ElapsedSince e) ns :: ElapsedSinceP UnixEpoch)
convertEpochWith :: (Epoch e1, Epoch e2) => (e1,e2) -> ElapsedSince e1 -> ElapsedSince e2
convertEpochWith (e1,e2) (ElapsedSince s1) = ElapsedSince (s1 + diff)
where diff = d1 d2
d1 = epochDiffToUnix e1
d2 = epochDiffToUnix e2
convertEpoch :: (Epoch e1, Epoch e2) => ElapsedSince e1 -> ElapsedSince e2
convertEpoch = convertEpochWith (undefined, undefined)
convertEpochPWith :: (Epoch e1, Epoch e2) => (e1,e2) -> ElapsedSinceP e1 -> ElapsedSinceP e2
convertEpochPWith es (ElapsedSinceP e1 n1) = ElapsedSinceP (convertEpochWith es e1) n1
convertEpochP :: (Epoch e1, Epoch e2) => ElapsedSinceP e1 -> ElapsedSinceP e2
convertEpochP = convertEpochPWith (undefined, undefined)