module Data.FlexibleTime
( (.+)
, (.-)
, getYear
, getMonth
, getDay
, getDate
, getHour
, getMin
, getSec
) where
import qualified Data.ByteString.Char8 as BS
import Data.UnixTime (Format, UnixTime, addUnixDiffTime,
diffUnixTime, formatUnixTime,
secondsToUnixDiffTime, udtSeconds)
import Foreign.C.Types (CTime (..))
import System.IO.Unsafe
(.+) :: (Integral a) => UnixTime -> a -> UnixTime
u .+ d = addUnixDiffTime u (secondsToUnixDiffTime d)
(.-) :: (Integral a) => UnixTime -> UnixTime -> a
l .- r = ctimeToIntegral $ udtSeconds $ diffUnixTime l r
getYear :: (Integral a) => UnixTime -> a
getYear = get "%Y"
getMonth :: (Integral a) => UnixTime -> a
getMonth = get "%m"
getDay :: (Integral a) => UnixTime -> a
getDay = get "%d"
getDate :: (Integral a) => UnixTime -> a
getDate = get "%w"
getHour :: (Integral a) => UnixTime -> a
getHour = get "%H"
getMin :: (Integral a) => UnixTime -> a
getMin = get "%M"
getSec :: (Integral a) => UnixTime -> a
getSec = get "%S"
ctimeToIntegral :: (Integral a) => CTime -> a
ctimeToIntegral (CTime n) = fromIntegral n
get :: (Integral a) => Format -> UnixTime -> a
get f = readBsNum . unsafePerformIO . formatUnixTime f
readBsNum :: (Integral a) => BS.ByteString -> a
readBsNum bs = go (reverse . map readChar . BS.unpack $ bs) 0 1
where
go [] num _ = num
go (x:xs) num cnt = go xs (num + (x * cnt)) (cnt*10)
readChar :: (Integral a) => Char -> a
readChar '0' = 0
readChar '1' = 1
readChar '2' = 2
readChar '3' = 3
readChar '4' = 4
readChar '5' = 5
readChar '6' = 6
readChar '7' = 7
readChar '8' = 8
readChar '9' = 9
readChar _ = error "parse error"