-- |This module provides functions to parse and format RFC 1123 date
-- and time formats.
--
-- The format is basically same as RFC 822, but the syntax for @date@
-- is changed from:
--
-- > year ::= 2DIGIT
--
-- to:
--
-- > year ::= 4DIGIT
module Data.Time.RFC1123
    ( format
    , parse
    )
    where

import qualified Text.Parsec as P

import Data.Time
import Data.Time.Calendar.WeekDate
import Data.Time.HTTP.Common
import Data.Time.RFC822 (showRFC822TimeZone)
import Data.Time.RFC1123.Parsec

-- |Format a 'ZonedTime' in RFC 1123.
format :: ZonedTime -> String
format zonedTime
    = let localTime          = zonedTimeToLocalTime zonedTime
          timeZone           = zonedTimeZone zonedTime
          (year, month, day) = toGregorian (localDay localTime)
          (_, _, week)       = toWeekDate  (localDay localTime)
          timeOfDay          = localTimeOfDay localTime
      in
        concat [ shortWeekDayName week
               , ", "
               , show2 day
               , " "
               , shortMonthName month
               , " "
               , show4 year
               , " "
               , show2 (todHour timeOfDay)
               , ":"
               , show2 (todMin timeOfDay)
               , ":"
               , show2 (floor (todSec timeOfDay))
               , " "
               , showRFC822TimeZone timeZone
               ]

-- |Parse an RFC 1123 date and time string. When the string can't be
-- parsed, it returns 'Nothing'.
parse :: String -> Maybe ZonedTime
parse src = case P.parse p "" src of
              Right zt -> Just zt
              Left  _  -> Nothing
    where
      p = do zt <- rfc1123DateAndTime
             _  <- P.eof
             return zt