module Data.Time.Clock.POSIX
(
posixDayLength,POSIXTime,posixSecondsToUTCTime,utcTimeToPOSIXSeconds,getPOSIXTime,getCurrentTime
) where
import Data.Time.Clock.UTC
import Data.Time.Calendar.Days
import Data.Fixed
import Control.Monad
#include "HsTimeConfig.h"
#ifdef mingw32_HOST_OS
import Data.Word ( Word64)
import System.Win32.Time
#elif HAVE_CLOCK_GETTIME
import Data.Time.Clock.CTimespec
import Foreign.C.Types (CTime(..))
#else
import Data.Time.Clock.CTimeval
#endif
posixDayLength :: NominalDiffTime
posixDayLength = 86400
type POSIXTime = NominalDiffTime
unixEpochDay :: Day
unixEpochDay = ModifiedJulianDay 40587
posixSecondsToUTCTime :: POSIXTime -> UTCTime
posixSecondsToUTCTime i = let
(d,t) = divMod' i posixDayLength
in UTCTime (addDays d unixEpochDay) (realToFrac t)
utcTimeToPOSIXSeconds :: UTCTime -> POSIXTime
utcTimeToPOSIXSeconds (UTCTime d t) =
(fromInteger (diffDays d unixEpochDay) * posixDayLength) + min posixDayLength (realToFrac t)
getPOSIXTime :: IO POSIXTime
#ifdef mingw32_HOST_OS
getPOSIXTime = do
FILETIME ft <- System.Win32.Time.getSystemTimeAsFileTime
return (fromIntegral (ft win32_epoch_adjust) / 10000000)
win32_epoch_adjust :: Word64
win32_epoch_adjust = 116444736000000000
#elif HAVE_CLOCK_GETTIME
ctimespecToPosixSeconds :: CTimespec -> POSIXTime
ctimespecToPosixSeconds (MkCTimespec (CTime s) ns) =
(fromIntegral s) + (fromIntegral ns) / 1000000000
getPOSIXTime = liftM ctimespecToPosixSeconds getCTimespec
#else
ctimevalToPosixSeconds :: CTimeval -> POSIXTime
ctimevalToPosixSeconds (MkCTimeval s mus) = (fromIntegral s) + (fromIntegral mus) / 1000000
getPOSIXTime = liftM ctimevalToPosixSeconds getCTimeval
#endif
getCurrentTime :: IO UTCTime
getCurrentTime = liftM posixSecondsToUTCTime getPOSIXTime