{-# LANGUAGE Safe #-}

module Data.Time.Clock.Internal.UTCTime (
    -- * UTC

    -- | UTC is time as measured by a clock, corrected to keep pace with the earth by adding or removing
    -- occasional seconds, known as \"leap seconds\".
    -- These corrections are not predictable and are announced with six month's notice.
    -- No table of these corrections is provided, as any program compiled with it would become
    -- out of date in six months.
    --
    -- If you don't care about leap seconds, use 'UTCTime' and 'NominalDiffTime' for your clock calculations,
    -- and you'll be fine.
    UTCTime (..),
) where

import Control.DeepSeq
import Data.Data
import Data.Time.Calendar.Days
import Data.Time.Clock.Internal.DiffTime

-- | This is the simplest representation of UTC.
-- It consists of the day number, and a time offset from midnight.
-- Note that if a day has a leap second added to it, it will have 86401 seconds.
data UTCTime = UTCTime
    { -- | the day
      UTCTime -> Day
utctDay :: Day
    , -- | the time from midnight, 0 <= t < 86401s (because of leap-seconds)
      UTCTime -> DiffTime
utctDayTime :: DiffTime
    }
    deriving (Typeable UTCTime
Typeable UTCTime
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> UTCTime -> c UTCTime)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c UTCTime)
-> (UTCTime -> Constr)
-> (UTCTime -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c UTCTime))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c UTCTime))
-> ((forall b. Data b => b -> b) -> UTCTime -> UTCTime)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> UTCTime -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> UTCTime -> r)
-> (forall u. (forall d. Data d => d -> u) -> UTCTime -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> UTCTime -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> UTCTime -> m UTCTime)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> UTCTime -> m UTCTime)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> UTCTime -> m UTCTime)
-> Data UTCTime
UTCTime -> Constr
UTCTime -> DataType
(forall b. Data b => b -> b) -> UTCTime -> UTCTime
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) -> UTCTime -> u
forall u. (forall d. Data d => d -> u) -> UTCTime -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> UTCTime -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> UTCTime -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> UTCTime -> m UTCTime
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> UTCTime -> m UTCTime
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c UTCTime
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> UTCTime -> c UTCTime
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c UTCTime)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c UTCTime)
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> UTCTime -> c UTCTime
gfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> UTCTime -> c UTCTime
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c UTCTime
gunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c UTCTime
$ctoConstr :: UTCTime -> Constr
toConstr :: UTCTime -> Constr
$cdataTypeOf :: UTCTime -> DataType
dataTypeOf :: UTCTime -> DataType
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c UTCTime)
dataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c UTCTime)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c UTCTime)
dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c UTCTime)
$cgmapT :: (forall b. Data b => b -> b) -> UTCTime -> UTCTime
gmapT :: (forall b. Data b => b -> b) -> UTCTime -> UTCTime
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> UTCTime -> r
gmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> UTCTime -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> UTCTime -> r
gmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> UTCTime -> r
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> UTCTime -> [u]
gmapQ :: forall u. (forall d. Data d => d -> u) -> UTCTime -> [u]
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> UTCTime -> u
gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> UTCTime -> u
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> UTCTime -> m UTCTime
gmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> UTCTime -> m UTCTime
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> UTCTime -> m UTCTime
gmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> UTCTime -> m UTCTime
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> UTCTime -> m UTCTime
gmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> UTCTime -> m UTCTime
Data, Typeable)

instance NFData UTCTime where
    rnf :: UTCTime -> ()
rnf (UTCTime Day
d DiffTime
t) = Day -> ()
forall a. NFData a => a -> ()
rnf Day
d () -> () -> ()
forall a b. a -> b -> b
`seq` DiffTime -> ()
forall a. NFData a => a -> ()
rnf DiffTime
t () -> () -> ()
forall a b. a -> b -> b
`seq` ()

instance Eq UTCTime where
    (UTCTime Day
da DiffTime
ta) == :: UTCTime -> UTCTime -> Bool
== (UTCTime Day
db DiffTime
tb) = (Day
da Day -> Day -> Bool
forall a. Eq a => a -> a -> Bool
== Day
db) Bool -> Bool -> Bool
&& (DiffTime
ta DiffTime -> DiffTime -> Bool
forall a. Eq a => a -> a -> Bool
== DiffTime
tb)

instance Ord UTCTime where
    compare :: UTCTime -> UTCTime -> Ordering
compare (UTCTime Day
da DiffTime
ta) (UTCTime Day
db DiffTime
tb) =
        case (Day -> Day -> Ordering
forall a. Ord a => a -> a -> Ordering
compare Day
da Day
db) of
            Ordering
EQ -> DiffTime -> DiffTime -> Ordering
forall a. Ord a => a -> a -> Ordering
compare DiffTime
ta DiffTime
tb
            Ordering
cmp -> Ordering
cmp