    {-# LANGUAGE Safe #-}

    -- | POSIX time, if you need to deal with timestamps and the like.
    -- Most people won't need this module.
    --
    -- You can use 'POSIXTime' to obtain integer/word timestamps. For example:
    --
    -- > import Data.Time
    -- > import Data.Time.Clock.POSIX
    -- > import Data.Int
    -- >
    -- > nanosSinceEpoch :: UTCTime -> Int64
    -- > nanosSinceEpoch =
    -- >     floor . (1e9 *) . nominalDiffTimeToSeconds . utcTimeToPOSIXSeconds
    -- >
    -- > main :: IO ()
    -- > main = do
    -- >     u <- getCurrentTime
    -- >     print $ nanosSinceEpoch u
    module Data.Time.Clock.POSIX
        ( posixDayLength
        , POSIXTime
        , posixSecondsToUTCTime
        , utcTimeToPOSIXSeconds
        , getPOSIXTime
        , getCurrentTime
        , systemToPOSIXTime
        ) where

    import Data.Fixed
    import Data.Time.Calendar.Days
    import Data.Time.Clock.Internal.POSIXTime
    import Data.Time.Clock.Internal.UTCTime
    import Data.Time.Clock.System

    posixSecondsToUTCTime :: POSIXTime -> UTCTime
    posixSecondsToUTCTime :: POSIXTime -> UTCTime
    posixSecondsToUTCTime POSIXTime
    i = let
        (Integer
    d, POSIXTime
    t) = POSIXTime -> POSIXTime -> (Integer, POSIXTime)
    forall a b. (Real a, Integral b) => a -> a -> (b, a)
    divMod' POSIXTime
    i POSIXTime
    posixDayLength
        in Day -> DiffTime -> UTCTime
    UTCTime (Integer -> Day -> Day
    addDays Integer
    d Day
    systemEpochDay) (POSIXTime -> DiffTime
    forall a b. (Real a, Fractional b) => a -> b
    realToFrac POSIXTime
    t)

    utcTimeToPOSIXSeconds :: UTCTime -> POSIXTime
    utcTimeToPOSIXSeconds :: UTCTime -> POSIXTime
    utcTimeToPOSIXSeconds (UTCTime Day
    d DiffTime
    t) =
        (Integer -> POSIXTime
    forall a. Num a => Integer -> a
    fromInteger (Day -> Day -> Integer
    diffDays Day
    d Day
    systemEpochDay) POSIXTime -> POSIXTime -> POSIXTime
    forall a. Num a => a -> a -> a
    * POSIXTime
    posixDayLength) POSIXTime -> POSIXTime -> POSIXTime
    forall a. Num a => a -> a -> a
    + POSIXTime -> POSIXTime -> POSIXTime
    forall a. Ord a => a -> a -> a
    min POSIXTime
    posixDayLength (DiffTime -> POSIXTime
    forall a b. (Real a, Fractional b) => a -> b
    realToFrac DiffTime
    t)

    systemToPOSIXTime :: SystemTime -> POSIXTime
    systemToPOSIXTime :: SystemTime -> POSIXTime
    systemToPOSIXTime (MkSystemTime Int64
    s Word32
    ns) = (Int64 -> POSIXTime
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int64
    s) POSIXTime -> POSIXTime -> POSIXTime
    forall a. Num a => a -> a -> a
    + (Word32 -> POSIXTime
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Word32
    ns) POSIXTime -> POSIXTime -> POSIXTime
    forall a. Num a => a -> a -> a
    * POSIXTime
    1E-9

    -- | Get the current POSIX time from the system clock.
    getPOSIXTime :: IO POSIXTime
    getPOSIXTime :: IO POSIXTime
    getPOSIXTime = (SystemTime -> POSIXTime) -> IO SystemTime -> IO POSIXTime
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap SystemTime -> POSIXTime
    systemToPOSIXTime IO SystemTime
    getSystemTime

    -- | Get the current 'UTCTime' from the system clock.
    getCurrentTime :: IO UTCTime
    getCurrentTime :: IO UTCTime
    getCurrentTime = SystemTime -> UTCTime
    systemToUTCTime (SystemTime -> UTCTime) -> IO SystemTime -> IO UTCTime
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    `fmap` IO SystemTime
    getSystemTime