module Network.HTTP.Lucu.RFC1123DateTime ( formatRFC1123DateTime , formatHTTPDateTime , parseHTTPDateTime ) where import Control.Monad import qualified Data.ByteString.Lazy.Char8 as B import Data.ByteString.Lazy.Char8 (ByteString) import Network.HTTP.Lucu.Parser import System.Time import System.Locale import Text.Printf month = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"] week = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"] formatRFC1123DateTime :: CalendarTime -> String formatRFC1123DateTime time = printf "%s, %02d %s %04d %02d:%02d:%02d %s" (week !! fromEnum (ctWDay time)) (ctDay time) (month !! fromEnum (ctMonth time)) (ctYear time) (ctHour time) (ctMin time) (ctSec time) (ctTZName time) formatHTTPDateTime :: ClockTime -> String formatHTTPDateTime = formatRFC1123DateTime . (\cal -> cal { ctTZName = "GMT" }) . toUTCTime parseHTTPDateTime :: String -> Maybe ClockTime parseHTTPDateTime src = case parseStr httpDateTime src of (Success ct, _) -> Just ct _ -> Nothing httpDateTime :: Parser ClockTime httpDateTime = do foldl (<|>) (fail "") (map string week) char ',' char ' ' day <- liftM read (count 2 digit) char ' ' mon <- foldl (<|>) (fail "") (map tryEqToFst (zip month [1..])) char ' ' year <- liftM read (count 4 digit) char ' ' hour <- liftM read (count 2 digit) char ':' min <- liftM read (count 2 digit) char ':' sec <- liftM read (count 2 digit) char ' ' string "GMT" eof return $ toClockTime $ CalendarTime { ctYear = year , ctMonth = toEnum (mon - 1) , ctDay = day , ctHour = hour , ctMin = min , ctSec = sec , ctPicosec = 0 , ctTZ = 0 , ctWDay = undefined , ctYDay = undefined , ctTZName = undefined , ctIsDST = undefined } where tryEqToFst :: (String, a) -> Parser a tryEqToFst (str, a) = string str >> return a