5 module Data.Time.RFC822.Internal
10 import Control.Applicative
11 import Data.Attoparsec.Char8
13 import Data.Time.HTTP.Common
15 -- |Parse an RFC 822 date and time string.
16 rfc822DateAndTime ∷ Parser ZonedTime
17 rfc822DateAndTime = dateTime
19 dateTime ∷ Parser ZonedTime
20 dateTime = do weekDay ← optionMaybe $
21 do w ← shortWeekDayNameP
29 -> assertWeekDayIsGood givenWD gregDay
30 (tod, timeZone) ← rfc822time
31 let lt = LocalTime gregDay tod
32 zt = ZonedTime lt timeZone
38 month ← shortMonthNameP
40 year ← (+ 1900) <$> read2
42 assertGregorianDateIsGood year month day
44 -- |Parse the time and time zone of an RFC 822 date and time string.
45 rfc822time ∷ Parser (TimeOfDay, TimeZone)
46 rfc822time = do tod ← hms
51 hms ∷ Parser TimeOfDay
53 minute ← char ':' *> read2
54 second ← option 0 (char ':' *> read2)
55 assertTimeOfDayIsGood hour minute second
57 zone ∷ Parser TimeZone
58 zone = choice [ string "UT" *> return (TimeZone 0 False "UT" )
59 , string "GMT" *> return (TimeZone 0 False "GMT")
61 *> choice [ string "ST" *> return (TimeZone ((-5) * 60) False "EST")
62 , string "DT" *> return (TimeZone ((-4) * 60) True "EDT")
65 *> choice [ string "ST" *> return (TimeZone ((-6) * 60) False "CST")
66 , string "DT" *> return (TimeZone ((-5) * 60) True "CDT")
69 *> choice [ string "ST" *> return (TimeZone ((-7) * 60) False "MST")
70 , string "DT" *> return (TimeZone ((-6) * 60) True "MDT")
71 , return (TimeZone ((-12) * 60) False "M")
74 *> choice [ string "ST" *> return (TimeZone ((-8) * 60) False "PST")
75 , string "DT" *> return (TimeZone ((-7) * 60) True "PDT")
77 , char 'Z' *> return (TimeZone 0 False "Z")
78 , char 'A' *> return (TimeZone ((-1) * 60) False "A")
79 , char 'N' *> return (TimeZone ( 1 * 60) False "N")
80 , char 'Y' *> return (TimeZone ( 12 * 60) False "Y")