-- |

-- 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 a b. IO (a -> b) -> IO a -> IO b
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 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