-- |
-- 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