    -- |
    -- Module      : Time.System
    -- License     : BSD-style
    -- Maintainer  : Vincent Hanquez <vincent@snarc.org>
    -- Stability   : experimental
    -- Portability : unknown
    --
    -- Get the system timezone and current time value in multiple formats
    --
    module Time.System
        (
        -- * Current time in computer friendly format
          timeCurrent
        , timeCurrentP
        -- * Current time in human friendly DateTime format
        , dateCurrent
        , localDateCurrent
        , localDateCurrentAt
        -- * System timezone
        , timezoneCurrent
        ) where

    import Control.Applicative
    import Time.Types
    import Data.Hourglass.Time
    import Data.Hourglass.Local
    import Data.Hourglass.Internal (systemGetElapsedP, systemGetElapsed, systemGetTimezone)

    -- | Get the current elapsed seconds since epoch
    timeCurrent :: IO Elapsed
    timeCurrent :: IO Elapsed
    timeCurrent = IO Elapsed
    systemGetElapsed

    -- | Get the current elapsed seconds (precise to the nanosecond) since epoch
    timeCurrentP :: IO ElapsedP
    timeCurrentP :: IO ElapsedP
    timeCurrentP = IO ElapsedP
    systemGetElapsedP

    -- | Get the current global date
    --
    -- This is equivalent to:
    --
    -- > timeGetDateTimeOfDay `fmap` timeCurrentP
    dateCurrent :: IO DateTime
    dateCurrent :: IO DateTime
    dateCurrent = ElapsedP -> DateTime
    forall t. Timeable t => t -> DateTime
    timeGetDateTimeOfDay (ElapsedP -> DateTime) -> IO ElapsedP -> IO DateTime
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> IO ElapsedP
    timeCurrentP

    -- | Get the localized date by using 'timezoneCurrent' and 'dateCurrent'
    localDateCurrent :: IO (LocalTime DateTime)
    localDateCurrent :: IO (LocalTime DateTime)
    localDateCurrent = TimezoneOffset -> LocalTime DateTime -> LocalTime DateTime
    forall t. Time t => TimezoneOffset -> LocalTime t -> LocalTime t
    localTimeSetTimezone (TimezoneOffset -> LocalTime DateTime -> LocalTime DateTime)
    -> IO TimezoneOffset
    -> IO (LocalTime DateTime -> LocalTime DateTime)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> IO TimezoneOffset
    timezoneCurrent
                                            IO (LocalTime DateTime -> LocalTime DateTime)
    -> IO (LocalTime DateTime) -> IO (LocalTime DateTime)
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> (DateTime -> LocalTime DateTime
    forall t. Time t => t -> LocalTime t
    localTimeFromGlobal (DateTime -> LocalTime DateTime)
    -> IO DateTime -> IO (LocalTime DateTime)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> IO DateTime
    dateCurrent)

    -- | Get the localized date at a specific timezone offset.
    localDateCurrentAt :: TimezoneOffset -> IO (LocalTime DateTime)
    localDateCurrentAt :: TimezoneOffset -> IO (LocalTime DateTime)
    localDateCurrentAt tz :: TimezoneOffset
    tz = TimezoneOffset -> LocalTime DateTime -> LocalTime DateTime
    forall t. Time t => TimezoneOffset -> LocalTime t -> LocalTime t
    localTimeSetTimezone TimezoneOffset
    tz (LocalTime DateTime -> LocalTime DateTime)
    -> (DateTime -> LocalTime DateTime)
    -> DateTime
    -> LocalTime DateTime
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . DateTime -> LocalTime DateTime
    forall t. Time t => t -> LocalTime t
    localTimeFromGlobal (DateTime -> LocalTime DateTime)
    -> IO DateTime -> IO (LocalTime DateTime)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> IO DateTime
    dateCurrent

    -- | Get the current timezone offset
    --
    -- This include daylight saving time when in operation.
    timezoneCurrent :: IO TimezoneOffset
    timezoneCurrent :: IO TimezoneOffset
    timezoneCurrent = IO TimezoneOffset
    systemGetTimezone