{-# LANGUAGE ForeignFunctionInterface #-} module Data.Time.Git (approxidate, io_approxidate, posixToUTC) where import Foreign import Foreign.C.Types import Foreign.C.String import Data.Time import Data.Time.Clock.POSIX import qualified Data.ByteString as BS import qualified Data.ByteString.UTF8 as BS (fromString) foreign import ccall unsafe "date.c approxidate_careful" c_approxidate_careful :: CString -> Ptr CInt -> IO CULong -- | Parse a date/time string and return Just a Unix timestamp. -- Return Nothing if the string could not be interpreted. -- If no timezone is in the string, the local timezone is used. -- This is not in IO and you cannot safely ask it to parse strings like -- \"now\" and \"yesterday\". approxidate :: String -> Maybe Integer approxidate = unsafePerformIO . io_approxidate -- | Convert a Unix timestamp to a UTCTime posixToUTC :: Integer -> UTCTime posixToUTC = posixSecondsToUTCTime . realToFrac -- | Parse a date/time string and return Just a Unix timestamp. -- Return Nothing if the string could not be interpreted. -- If no timezone is in the string, the local timezone is used. -- This is in IO so that you can safely ask it to parse strings like -- \"now\" and \"yesterday\". io_approxidate :: String -> IO (Maybe Integer) io_approxidate input = BS.useAsCString (BS.fromString input) (\c_input -> alloca (\c_error_ret -> do poke c_error_ret 0 time <- c_approxidate_careful c_input c_error_ret err <- peek c_error_ret if err == 0 then return $ Just (toInteger time) else return Nothing ) )