{-# LANGUAGE Safe #-} module Data.UTC.Class.HasUnixTime where import Control.Monad.Catch import Data.Ratio import System.Clock as C import Data.UTC.Class.IsUnixTime import Data.UTC.Type.Exception -- | This class defines an interface for contexts that can be asked for a timestamp. -- -- Most users are likely to just need the 'Prelude.IO' instance, but you might -- think of other instances: -- -- - A wrapper around the system clock with internal state that ensures -- strict monotonically increasing values. -- - A custom monadic computation that needs time, but should not be given -- 'Prelude.IO' access. -- - Testing contexts where you might want to inject and test specific timestamps. class HasUnixTime m where -- | Get a timestamp from the surrounding context. The 'Prelude.IO' instance gives -- access to the __system clock__ and is what most users are probably looking for. -- -- /Beware:/ The 'Prelude.IO' instance does __not__ guarantee that -- subsequent calls are monotonically increasing. The system's clock might -- stop or even go backwards when synchronised manually or via NTP or when -- adapting to a leap second. -- -- /Example:/ -- -- > import Data.UTC -- > -- > printCurrentYear :: IO () -- > printCurrentYear -- > = do now <- getUnixTime :: IO DateTime -- > print (year now) getUnixTime :: (Monad m, IsUnixTime a) => m a instance HasUnixTime IO where getUnixTime = do TimeSpec s ns <- C.getTime Realtime case fromUnixSeconds ((fromIntegral s) % 1 + (fromIntegral ns) % 1000000000) of Just t -> return t Nothing -> throwM $ UtcException "HasUnixTime IO: getUnixTime"