module Network.Web.Date (parseDate, utcToDate, HttpDate) where
import Control.Monad
import qualified Data.ByteString.Char8 as S
import Data.Time
import System.Locale
type HttpDate = S.ByteString
parseDate :: S.ByteString -> Maybe UTCTime
parseDate bs = rfc1123Date cs `mplus` rfc850Date cs `mplus` asctimeDate cs
where
cs = S.unpack bs
rfc1123Format :: String
rfc1123Format = "%a, %d %b %Y %H:%M:%S GMT"
rfc850Format :: String
rfc850Format = "%A, %d-%b-%y %H:%M:%S GMT"
asctimeFormat :: String
asctimeFormat = "%a %b %e %H:%M:%S %Y"
preferredFormat :: String
preferredFormat = rfc1123Format
rfc1123Date :: String -> Maybe UTCTime
rfc1123Date = parseTime defaultTimeLocale preferredFormat
rfc850Date :: String -> Maybe UTCTime
rfc850Date str = parseTime defaultTimeLocale rfc850Format str >>= y2k
where
y2k utct = let (y,m,d) = toGregorian $ utctDay utct
in if y < 1950
then Just utct { utctDay = fromGregorian (y+100) m d }
else Just utct
asctimeDate :: String -> Maybe UTCTime
asctimeDate = parseTime defaultTimeLocale asctimeFormat
utcToDate :: UTCTime -> HttpDate
utcToDate = S.pack . formatTime defaultTimeLocale preferredFormat