{-# LANGUAGE DataKinds #-}
{-# LANGUAGE ExplicitForAll #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
module Time.Timestamp
( Timestamp (..)
, fromUnixTime
, timeDiff
, timeAdd
, timeMul
, (*:*)
, timeDiv
, (/:/)
, (+:+)
, (-:-)
, (-%-)
) where
import Data.Coerce (coerce)
import Time.Rational (KnownDivRat, KnownRat, Rat, RatioNat)
import Time.Units (Second, Time (..), sec, toUnit)
newtype Timestamp = Timestamp Rational
deriving (Int -> Timestamp -> ShowS
[Timestamp] -> ShowS
Timestamp -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Timestamp] -> ShowS
$cshowList :: [Timestamp] -> ShowS
show :: Timestamp -> String
$cshow :: Timestamp -> String
showsPrec :: Int -> Timestamp -> ShowS
$cshowsPrec :: Int -> Timestamp -> ShowS
Show, ReadPrec [Timestamp]
ReadPrec Timestamp
Int -> ReadS Timestamp
ReadS [Timestamp]
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [Timestamp]
$creadListPrec :: ReadPrec [Timestamp]
readPrec :: ReadPrec Timestamp
$creadPrec :: ReadPrec Timestamp
readList :: ReadS [Timestamp]
$creadList :: ReadS [Timestamp]
readsPrec :: Int -> ReadS Timestamp
$creadsPrec :: Int -> ReadS Timestamp
Read, Timestamp -> Timestamp -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Timestamp -> Timestamp -> Bool
$c/= :: Timestamp -> Timestamp -> Bool
== :: Timestamp -> Timestamp -> Bool
$c== :: Timestamp -> Timestamp -> Bool
Eq, Eq Timestamp
Timestamp -> Timestamp -> Bool
Timestamp -> Timestamp -> Ordering
Timestamp -> Timestamp -> Timestamp
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: Timestamp -> Timestamp -> Timestamp
$cmin :: Timestamp -> Timestamp -> Timestamp
max :: Timestamp -> Timestamp -> Timestamp
$cmax :: Timestamp -> Timestamp -> Timestamp
>= :: Timestamp -> Timestamp -> Bool
$c>= :: Timestamp -> Timestamp -> Bool
> :: Timestamp -> Timestamp -> Bool
$c> :: Timestamp -> Timestamp -> Bool
<= :: Timestamp -> Timestamp -> Bool
$c<= :: Timestamp -> Timestamp -> Bool
< :: Timestamp -> Timestamp -> Bool
$c< :: Timestamp -> Timestamp -> Bool
compare :: Timestamp -> Timestamp -> Ordering
$ccompare :: Timestamp -> Timestamp -> Ordering
Ord)
fromUnixTime :: Real a => a -> Timestamp
fromUnixTime :: forall a. Real a => a -> Timestamp
fromUnixTime = Rational -> Timestamp
Timestamp forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Real a => a -> Rational
toRational
timeDiff :: forall (unit :: Rat) . KnownDivRat Second unit
=> Timestamp
-> Timestamp
-> (Ordering, Time unit)
timeDiff :: forall (unit :: Rat).
KnownDivRat Second unit =>
Timestamp -> Timestamp -> (Ordering, Time unit)
timeDiff (Timestamp Rational
a) (Timestamp Rational
b) =
let (Ordering
order, RatioNat
r) = Rational -> Rational -> (Ordering, RatioNat)
ratDiff Rational
a Rational
b
in (Ordering
order, forall (unitTo :: Rat) (unitFrom :: Rat).
KnownDivRat unitFrom unitTo =>
Time unitFrom -> Time unitTo
toUnit forall a b. (a -> b) -> a -> b
$ RatioNat -> Time Second
sec RatioNat
r)
timeAdd :: forall (unit :: Rat) . KnownDivRat unit Second
=> Time unit
-> Timestamp
-> Timestamp
timeAdd :: forall (unit :: Rat).
KnownDivRat unit Second =>
Time unit -> Timestamp -> Timestamp
timeAdd Time unit
t (Timestamp Rational
ts) = Rational -> Timestamp
Timestamp (forall a. Real a => a -> Rational
toRational (forall (rat :: Rat). Time rat -> RatioNat
unTime forall a b. (a -> b) -> a -> b
$ forall (unitTo :: Rat) (unitFrom :: Rat).
KnownDivRat unitFrom unitTo =>
Time unitFrom -> Time unitTo
toUnit @Second Time unit
t) forall a. Num a => a -> a -> a
+ Rational
ts)
timeMul :: forall (unit :: Rat) .
RatioNat
-> Time unit
-> Time unit
timeMul :: forall (unit :: Rat). RatioNat -> Time unit -> Time unit
timeMul RatioNat
n (Time RatioNat
t) = forall (rat :: Rat). RatioNat -> Time rat
Time (RatioNat
n forall a. Num a => a -> a -> a
* RatioNat
t)
infixr 7 *:*
(*:*) :: forall (unit :: Rat) . KnownRat unit
=> RatioNat -> Time unit -> Time unit
*:* :: forall (unit :: Rat).
KnownRat unit =>
RatioNat -> Time unit -> Time unit
(*:*) = forall (unit :: Rat). RatioNat -> Time unit -> Time unit
timeMul
timeDiv :: forall (unit :: Rat) . KnownRat unit
=> Time unit
-> Time unit
-> RatioNat
timeDiv :: forall (unit :: Rat).
KnownRat unit =>
Time unit -> Time unit -> RatioNat
timeDiv (Time RatioNat
t1) (Time RatioNat
t2) = RatioNat
t1 forall a. Fractional a => a -> a -> a
/ RatioNat
t2
infix 7 /:/
(/:/) :: forall (unit :: Rat) . KnownRat unit
=> Time unit -> Time unit -> RatioNat
/:/ :: forall (unit :: Rat).
KnownRat unit =>
Time unit -> Time unit -> RatioNat
(/:/) = forall (unit :: Rat).
KnownRat unit =>
Time unit -> Time unit -> RatioNat
timeDiv
infixl 6 +:+
(+:+) :: forall (unitResult :: Rat) (unitLeft :: Rat) . KnownDivRat unitLeft unitResult
=> Time unitLeft
-> Time unitResult
-> Time unitResult
Time unitLeft
t1 +:+ :: forall (unitResult :: Rat) (unitLeft :: Rat).
KnownDivRat unitLeft unitResult =>
Time unitLeft -> Time unitResult -> Time unitResult
+:+ Time unitResult
t2 = coerce :: forall a b. Coercible a b => a -> b
coerce (forall a. Num a => a -> a -> a
(+) :: RatioNat -> RatioNat -> RatioNat) (forall (unitTo :: Rat) (unitFrom :: Rat).
KnownDivRat unitFrom unitTo =>
Time unitFrom -> Time unitTo
toUnit @unitResult Time unitLeft
t1) Time unitResult
t2
{-# INLINE (+:+) #-}
infixl 6 -:-
(-:-) :: forall (unitResult :: Rat) (unitLeft :: Rat) . KnownDivRat unitLeft unitResult
=> Time unitLeft
-> Time unitResult
-> Time unitResult
Time unitLeft
t1 -:- :: forall (unitResult :: Rat) (unitLeft :: Rat).
KnownDivRat unitLeft unitResult =>
Time unitLeft -> Time unitResult -> Time unitResult
-:- Time unitResult
t2 = coerce :: forall a b. Coercible a b => a -> b
coerce ((-) :: RatioNat -> RatioNat -> RatioNat) (forall (unitTo :: Rat) (unitFrom :: Rat).
KnownDivRat unitFrom unitTo =>
Time unitFrom -> Time unitTo
toUnit @unitResult Time unitLeft
t1) Time unitResult
t2
{-# INLINE (-:-) #-}
infix 6 -%-
(-%-) :: forall (unitResult :: Rat) (unitLeft :: Rat) . KnownDivRat unitLeft unitResult
=> Time unitLeft
-> Time unitResult
-> (Ordering, Time unitResult)
Time unitLeft
t1 -%- :: forall (unitResult :: Rat) (unitLeft :: Rat).
KnownDivRat unitLeft unitResult =>
Time unitLeft -> Time unitResult -> (Ordering, Time unitResult)
-%- (Time RatioNat
t2Rat) =
let (Time RatioNat
t1Rat) = forall (unitTo :: Rat) (unitFrom :: Rat).
KnownDivRat unitFrom unitTo =>
Time unitFrom -> Time unitTo
toUnit @unitResult Time unitLeft
t1
(Ordering
order, RatioNat
rat) = Rational -> Rational -> (Ordering, RatioNat)
ratDiff (forall a. Real a => a -> Rational
toRational RatioNat
t1Rat) (forall a. Real a => a -> Rational
toRational RatioNat
t2Rat)
in (Ordering
order, forall (rat :: Rat). RatioNat -> Time rat
Time RatioNat
rat)
ratDiff :: Rational -> Rational -> (Ordering, RatioNat)
ratDiff :: Rational -> Rational -> (Ordering, RatioNat)
ratDiff Rational
r1 Rational
r2 =
let order :: Ordering
order = forall a. Ord a => a -> a -> Ordering
compare Rational
r1 Rational
r2
diff :: RatioNat
diff = forall a. Fractional a => Rational -> a
fromRational forall a b. (a -> b) -> a -> b
$ case Ordering
order of
Ordering
LT -> Rational
r2 forall a. Num a => a -> a -> a
- Rational
r1
Ordering
GT -> Rational
r1 forall a. Num a => a -> a -> a
- Rational
r2
Ordering
EQ -> Rational
0
in (Ordering
order, RatioNat
diff)