{-# LANGUAGE Trustworthy #-}

module Data.Time.Clock.Internal.NominalDiffTime (
    NominalDiffTime,
    secondsToNominalDiffTime,
    nominalDiffTimeToSeconds,
    nominalDay,
) where

import Control.DeepSeq
import Data.Data
import Data.Fixed
import GHC.Read
import Text.ParserCombinators.ReadP
import Text.ParserCombinators.ReadPrec

-- | This is a length of time, as measured by UTC.
-- It has a precision of 10^-12 s.
--
-- Conversion functions such as 'fromInteger' and 'realToFrac' will treat it as seconds.
-- For example, @(0.010 :: NominalDiffTime)@ corresponds to 10 milliseconds.
--
-- It has a precision of one picosecond (= 10^-12 s). Enumeration functions will treat it as picoseconds.
--
-- It ignores leap-seconds, so it's not necessarily a fixed amount of clock time.
-- For instance, 23:00 UTC + 2 hours of NominalDiffTime = 01:00 UTC (+ 1 day),
-- regardless of whether a leap-second intervened.
newtype NominalDiffTime
    = MkNominalDiffTime Pico
    deriving (NominalDiffTime -> NominalDiffTime -> Bool
(NominalDiffTime -> NominalDiffTime -> Bool)
-> (NominalDiffTime -> NominalDiffTime -> Bool)
-> Eq NominalDiffTime
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: NominalDiffTime -> NominalDiffTime -> Bool
== :: NominalDiffTime -> NominalDiffTime -> Bool
$c/= :: NominalDiffTime -> NominalDiffTime -> Bool
/= :: NominalDiffTime -> NominalDiffTime -> Bool
Eq, Eq NominalDiffTime
Eq NominalDiffTime
-> (NominalDiffTime -> NominalDiffTime -> Ordering)
-> (NominalDiffTime -> NominalDiffTime -> Bool)
-> (NominalDiffTime -> NominalDiffTime -> Bool)
-> (NominalDiffTime -> NominalDiffTime -> Bool)
-> (NominalDiffTime -> NominalDiffTime -> Bool)
-> (NominalDiffTime -> NominalDiffTime -> NominalDiffTime)
-> (NominalDiffTime -> NominalDiffTime -> NominalDiffTime)
-> Ord NominalDiffTime
NominalDiffTime -> NominalDiffTime -> Bool
NominalDiffTime -> NominalDiffTime -> Ordering
NominalDiffTime -> NominalDiffTime -> NominalDiffTime
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
$ccompare :: NominalDiffTime -> NominalDiffTime -> Ordering
compare :: NominalDiffTime -> NominalDiffTime -> Ordering
$c< :: NominalDiffTime -> NominalDiffTime -> Bool
< :: NominalDiffTime -> NominalDiffTime -> Bool
$c<= :: NominalDiffTime -> NominalDiffTime -> Bool
<= :: NominalDiffTime -> NominalDiffTime -> Bool
$c> :: NominalDiffTime -> NominalDiffTime -> Bool
> :: NominalDiffTime -> NominalDiffTime -> Bool
$c>= :: NominalDiffTime -> NominalDiffTime -> Bool
>= :: NominalDiffTime -> NominalDiffTime -> Bool
$cmax :: NominalDiffTime -> NominalDiffTime -> NominalDiffTime
max :: NominalDiffTime -> NominalDiffTime -> NominalDiffTime
$cmin :: NominalDiffTime -> NominalDiffTime -> NominalDiffTime
min :: NominalDiffTime -> NominalDiffTime -> NominalDiffTime
Ord, Typeable NominalDiffTime
Typeable NominalDiffTime
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> NominalDiffTime -> c NominalDiffTime)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c NominalDiffTime)
-> (NominalDiffTime -> Constr)
-> (NominalDiffTime -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c NominalDiffTime))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c NominalDiffTime))
-> ((forall b. Data b => b -> b)
    -> NominalDiffTime -> NominalDiffTime)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> NominalDiffTime -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> NominalDiffTime -> r)
-> (forall u.
    (forall d. Data d => d -> u) -> NominalDiffTime -> [u])
-> (forall u.
    Int -> (forall d. Data d => d -> u) -> NominalDiffTime -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d)
    -> NominalDiffTime -> m NominalDiffTime)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d)
    -> NominalDiffTime -> m NominalDiffTime)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d)
    -> NominalDiffTime -> m NominalDiffTime)
-> Data NominalDiffTime
NominalDiffTime -> Constr
NominalDiffTime -> DataType
(forall b. Data b => b -> b) -> NominalDiffTime -> NominalDiffTime
forall a.
Typeable a
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u.
Int -> (forall d. Data d => d -> u) -> NominalDiffTime -> u
forall u. (forall d. Data d => d -> u) -> NominalDiffTime -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> NominalDiffTime -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> NominalDiffTime -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d)
-> NominalDiffTime -> m NominalDiffTime
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d)
-> NominalDiffTime -> m NominalDiffTime
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c NominalDiffTime
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> NominalDiffTime -> c NominalDiffTime
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c NominalDiffTime)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c NominalDiffTime)
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> NominalDiffTime -> c NominalDiffTime
gfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> NominalDiffTime -> c NominalDiffTime
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c NominalDiffTime
gunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c NominalDiffTime
$ctoConstr :: NominalDiffTime -> Constr
toConstr :: NominalDiffTime -> Constr
$cdataTypeOf :: NominalDiffTime -> DataType
dataTypeOf :: NominalDiffTime -> DataType
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c NominalDiffTime)
dataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c NominalDiffTime)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c NominalDiffTime)
dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c NominalDiffTime)
$cgmapT :: (forall b. Data b => b -> b) -> NominalDiffTime -> NominalDiffTime
gmapT :: (forall b. Data b => b -> b) -> NominalDiffTime -> NominalDiffTime
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> NominalDiffTime -> r
gmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> NominalDiffTime -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> NominalDiffTime -> r
gmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> NominalDiffTime -> r
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> NominalDiffTime -> [u]
gmapQ :: forall u. (forall d. Data d => d -> u) -> NominalDiffTime -> [u]
$cgmapQi :: forall u.
Int -> (forall d. Data d => d -> u) -> NominalDiffTime -> u
gmapQi :: forall u.
Int -> (forall d. Data d => d -> u) -> NominalDiffTime -> u
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d)
-> NominalDiffTime -> m NominalDiffTime
gmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d)
-> NominalDiffTime -> m NominalDiffTime
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d)
-> NominalDiffTime -> m NominalDiffTime
gmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d)
-> NominalDiffTime -> m NominalDiffTime
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d)
-> NominalDiffTime -> m NominalDiffTime
gmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d)
-> NominalDiffTime -> m NominalDiffTime
Data, Typeable)

-- | Create a 'NominalDiffTime' from a number of seconds.
--
-- @since 1.9.1
secondsToNominalDiffTime :: Pico -> NominalDiffTime
secondsToNominalDiffTime :: Pico -> NominalDiffTime
secondsToNominalDiffTime = Pico -> NominalDiffTime
MkNominalDiffTime

-- | Get the seconds in a 'NominalDiffTime'.
--
-- @since 1.9.1
nominalDiffTimeToSeconds :: NominalDiffTime -> Pico
nominalDiffTimeToSeconds :: NominalDiffTime -> Pico
nominalDiffTimeToSeconds (MkNominalDiffTime Pico
t) = Pico
t

instance NFData NominalDiffTime where
    rnf :: NominalDiffTime -> ()
rnf (MkNominalDiffTime Pico
t) = Pico -> ()
forall a. NFData a => a -> ()
rnf Pico
t

instance Enum NominalDiffTime where
    succ :: NominalDiffTime -> NominalDiffTime
succ (MkNominalDiffTime Pico
a) = Pico -> NominalDiffTime
MkNominalDiffTime (Pico -> Pico
forall a. Enum a => a -> a
succ Pico
a)
    pred :: NominalDiffTime -> NominalDiffTime
pred (MkNominalDiffTime Pico
a) = Pico -> NominalDiffTime
MkNominalDiffTime (Pico -> Pico
forall a. Enum a => a -> a
pred Pico
a)
    toEnum :: Int -> NominalDiffTime
toEnum = Pico -> NominalDiffTime
MkNominalDiffTime (Pico -> NominalDiffTime)
-> (Int -> Pico) -> Int -> NominalDiffTime
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Pico
forall a. Enum a => Int -> a
toEnum
    fromEnum :: NominalDiffTime -> Int
fromEnum (MkNominalDiffTime Pico
a) = Pico -> Int
forall a. Enum a => a -> Int
fromEnum Pico
a
    enumFrom :: NominalDiffTime -> [NominalDiffTime]
enumFrom (MkNominalDiffTime Pico
a) = (Pico -> NominalDiffTime) -> [Pico] -> [NominalDiffTime]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Pico -> NominalDiffTime
MkNominalDiffTime (Pico -> [Pico]
forall a. Enum a => a -> [a]
enumFrom Pico
a)
    enumFromThen :: NominalDiffTime -> NominalDiffTime -> [NominalDiffTime]
enumFromThen (MkNominalDiffTime Pico
a) (MkNominalDiffTime Pico
b) = (Pico -> NominalDiffTime) -> [Pico] -> [NominalDiffTime]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Pico -> NominalDiffTime
MkNominalDiffTime (Pico -> Pico -> [Pico]
forall a. Enum a => a -> a -> [a]
enumFromThen Pico
a Pico
b)
    enumFromTo :: NominalDiffTime -> NominalDiffTime -> [NominalDiffTime]
enumFromTo (MkNominalDiffTime Pico
a) (MkNominalDiffTime Pico
b) = (Pico -> NominalDiffTime) -> [Pico] -> [NominalDiffTime]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Pico -> NominalDiffTime
MkNominalDiffTime (Pico -> Pico -> [Pico]
forall a. Enum a => a -> a -> [a]
enumFromTo Pico
a Pico
b)
    enumFromThenTo :: NominalDiffTime
-> NominalDiffTime -> NominalDiffTime -> [NominalDiffTime]
enumFromThenTo (MkNominalDiffTime Pico
a) (MkNominalDiffTime Pico
b) (MkNominalDiffTime Pico
c) =
        (Pico -> NominalDiffTime) -> [Pico] -> [NominalDiffTime]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Pico -> NominalDiffTime
MkNominalDiffTime (Pico -> Pico -> Pico -> [Pico]
forall a. Enum a => a -> a -> a -> [a]
enumFromThenTo Pico
a Pico
b Pico
c)

instance Show NominalDiffTime where
    show :: NominalDiffTime -> String
show (MkNominalDiffTime Pico
t) = (Bool -> Pico -> String
forall {k} (a :: k). HasResolution a => Bool -> Fixed a -> String
showFixed Bool
True Pico
t) String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"s"

instance Read NominalDiffTime where
    readPrec :: ReadPrec NominalDiffTime
readPrec = do
        Pico
t <- ReadPrec Pico
forall a. Read a => ReadPrec a
readPrec
        Char
_ <- ReadP Char -> ReadPrec Char
forall a. ReadP a -> ReadPrec a
lift (ReadP Char -> ReadPrec Char) -> ReadP Char -> ReadPrec Char
forall a b. (a -> b) -> a -> b
$ Char -> ReadP Char
char Char
's'
        NominalDiffTime -> ReadPrec NominalDiffTime
forall a. a -> ReadPrec a
forall (m :: * -> *) a. Monad m => a -> m a
return (NominalDiffTime -> ReadPrec NominalDiffTime)
-> NominalDiffTime -> ReadPrec NominalDiffTime
forall a b. (a -> b) -> a -> b
$ Pico -> NominalDiffTime
MkNominalDiffTime Pico
t

instance Num NominalDiffTime where
    (MkNominalDiffTime Pico
a) + :: NominalDiffTime -> NominalDiffTime -> NominalDiffTime
+ (MkNominalDiffTime Pico
b) = Pico -> NominalDiffTime
MkNominalDiffTime (Pico
a Pico -> Pico -> Pico
forall a. Num a => a -> a -> a
+ Pico
b)
    (MkNominalDiffTime Pico
a) - :: NominalDiffTime -> NominalDiffTime -> NominalDiffTime
- (MkNominalDiffTime Pico
b) = Pico -> NominalDiffTime
MkNominalDiffTime (Pico
a Pico -> Pico -> Pico
forall a. Num a => a -> a -> a
- Pico
b)
    (MkNominalDiffTime Pico
a) * :: NominalDiffTime -> NominalDiffTime -> NominalDiffTime
* (MkNominalDiffTime Pico
b) = Pico -> NominalDiffTime
MkNominalDiffTime (Pico
a Pico -> Pico -> Pico
forall a. Num a => a -> a -> a
* Pico
b)
    negate :: NominalDiffTime -> NominalDiffTime
negate (MkNominalDiffTime Pico
a) = Pico -> NominalDiffTime
MkNominalDiffTime (Pico -> Pico
forall a. Num a => a -> a
negate Pico
a)
    abs :: NominalDiffTime -> NominalDiffTime
abs (MkNominalDiffTime Pico
a) = Pico -> NominalDiffTime
MkNominalDiffTime (Pico -> Pico
forall a. Num a => a -> a
abs Pico
a)
    signum :: NominalDiffTime -> NominalDiffTime
signum (MkNominalDiffTime Pico
a) = Pico -> NominalDiffTime
MkNominalDiffTime (Pico -> Pico
forall a. Num a => a -> a
signum Pico
a)
    fromInteger :: Integer -> NominalDiffTime
fromInteger Integer
i = Pico -> NominalDiffTime
MkNominalDiffTime (Integer -> Pico
forall a. Num a => Integer -> a
fromInteger Integer
i)

instance Real NominalDiffTime where
    toRational :: NominalDiffTime -> Rational
toRational (MkNominalDiffTime Pico
a) = Pico -> Rational
forall a. Real a => a -> Rational
toRational Pico
a

instance Fractional NominalDiffTime where
    (MkNominalDiffTime Pico
a) / :: NominalDiffTime -> NominalDiffTime -> NominalDiffTime
/ (MkNominalDiffTime Pico
b) = Pico -> NominalDiffTime
MkNominalDiffTime (Pico
a Pico -> Pico -> Pico
forall a. Fractional a => a -> a -> a
/ Pico
b)
    recip :: NominalDiffTime -> NominalDiffTime
recip (MkNominalDiffTime Pico
a) = Pico -> NominalDiffTime
MkNominalDiffTime (Pico -> Pico
forall a. Fractional a => a -> a
recip Pico
a)
    fromRational :: Rational -> NominalDiffTime
fromRational Rational
r = Pico -> NominalDiffTime
MkNominalDiffTime (Rational -> Pico
forall a. Fractional a => Rational -> a
fromRational Rational
r)

instance RealFrac NominalDiffTime where
    properFraction :: forall b. Integral b => NominalDiffTime -> (b, NominalDiffTime)
properFraction (MkNominalDiffTime Pico
a) = (b
i, Pico -> NominalDiffTime
MkNominalDiffTime Pico
f)
      where
        (b
i, Pico
f) = Pico -> (b, Pico)
forall b. Integral b => Pico -> (b, Pico)
forall a b. (RealFrac a, Integral b) => a -> (b, a)
properFraction Pico
a
    truncate :: forall b. Integral b => NominalDiffTime -> b
truncate (MkNominalDiffTime Pico
a) = Pico -> b
forall b. Integral b => Pico -> b
forall a b. (RealFrac a, Integral b) => a -> b
truncate Pico
a
    round :: forall b. Integral b => NominalDiffTime -> b
round (MkNominalDiffTime Pico
a) = Pico -> b
forall b. Integral b => Pico -> b
forall a b. (RealFrac a, Integral b) => a -> b
round Pico
a
    ceiling :: forall b. Integral b => NominalDiffTime -> b
ceiling (MkNominalDiffTime Pico
a) = Pico -> b
forall b. Integral b => Pico -> b
forall a b. (RealFrac a, Integral b) => a -> b
ceiling Pico
a
    floor :: forall b. Integral b => NominalDiffTime -> b
floor (MkNominalDiffTime Pico
a) = Pico -> b
forall b. Integral b => Pico -> b
forall a b. (RealFrac a, Integral b) => a -> b
floor Pico
a

{-# RULES
"realToFrac/DiffTime->NominalDiffTime"
    realToFrac =
        \dt -> MkNominalDiffTime (realToFrac dt)
"realToFrac/NominalDiffTime->DiffTime"
    realToFrac =
        \(MkNominalDiffTime ps) -> realToFrac ps
"realToFrac/NominalDiffTime->Pico"
    realToFrac =
        \(MkNominalDiffTime ps) -> ps
"realToFrac/Pico->NominalDiffTime" realToFrac = MkNominalDiffTime
    #-}

-- | One day in 'NominalDiffTime'.
nominalDay :: NominalDiffTime
nominalDay :: NominalDiffTime
nominalDay = NominalDiffTime
86400