{-# LANGUAGE FlexibleContexts #-}
module Data.Time.RFC1123.Parsec
    ( rfc1123DateAndTime
    )
    where

import Control.Monad
import Data.Fixed
import Data.Time
import Data.Time.Calendar.WeekDate
import Data.Time.HTTP.Common
import Data.Time.RFC822.Parsec
import Text.Parsec

-- |This is a parsec parser for RFC 1123 date and time strings.
rfc1123DateAndTime :: Stream s m Char => ParsecT s u m ZonedTime
rfc1123DateAndTime = dateTime

dateTime :: Stream s m Char => ParsecT s u m ZonedTime
dateTime = do weekDay <- optionMaybe $
                         do w <- shortWeekDayNameP
                            _ <- string ", "
                            return w
              gregDay <- date
              case weekDay of
                Nothing
                    -> return () -- No day in week exists.
                Just givenWD
                    -> assertWeekDayIsGood givenWD gregDay
              (tod, timeZone) <- rfc822time
              let lt = LocalTime gregDay tod
                  zt = ZonedTime lt timeZone
              return zt

date :: Stream s m Char => ParsecT s u m Day
date = do day   <- read2
          _     <- char ' '
          month <- shortMonthNameP
          _     <- char ' '
          year  <- read4
          _     <- char ' '
          assertGregorianDateIsGood year month day