1 {-# LANGUAGE FlexibleContexts #-}
2 module Data.Time.RFC822.Parsec
10 import Data.Time.Calendar.WeekDate
11 import Data.Time.HTTP.Common
15 parser :: Stream s m Char => ParsecT s u m ZonedTime
19 dateTime :: Stream s m Char => ParsecT s u m ZonedTime
20 dateTime = do weekDay <- optionMaybe $
21 do w <- shortWeekDayNameP
27 -> return () -- No day in week exists.
29 -> let (_, _, correctWD) = toWeekDate gregDay
31 if correctWD == givenWD then
32 return () -- Correct day in the week.
34 let (year, month, day) = toGregorian gregDay
36 fail $ concat [ "Gregorian day "
43 , longWeekDayName correctWD
45 , longWeekDayName givenWD
47 (tod, timeZone) <- time
49 zonedTimeToLocalTime = LocalTime {
51 , localTimeOfDay = tod
53 , zonedTimeZone = timeZone
56 date :: Stream s m Char => ParsecT s u m Day
57 date = do day <- read2
59 month <- shortMonthNameP
61 year <- liftM (+ 1900) read2
64 case fromGregorianValid (toInteger year) month day of
66 -> fail $ concat [ "Invalid gregorian day: "
76 time :: Stream s m Char => ParsecT s u m (TimeOfDay, TimeZone)
82 hour :: Stream s m Char => ParsecT s u m TimeOfDay
83 hour = do hour <- read2
84 minute <- char ':' >> read2
85 second <- option 0 (char ':' >> read2)
86 case makeTimeOfDayValid hour minute second of
88 -> fail $ concat [ "Invalid time of day: "
93 , showFixed True second
98 zone :: Stream s m Char => ParsecT s u m TimeZone
99 zone = choice [ string "UT" >> return (TimeZone 0 False "UT" )
100 , string "GMT" >> return (TimeZone 0 False "GMT")
102 >> choice [ string "ST" >> return (TimeZone ((-5) * 60) False "EST")
103 , string "DT" >> return (TimeZone ((-4) * 60) True "EDT")
106 >> choice [ string "ST" >> return (TimeZone ((-6) * 60) False "CST")
107 , string "DT" >> return (TimeZone ((-5) * 60) True "CDT")
110 >> choice [ string "ST" >> return (TimeZone ((-7) * 60) False "MST")
111 , string "DT" >> return (TimeZone ((-6) * 60) True "MDT")
112 , return (TimeZone ((-12) * 60) False "M")
115 >> choice [ string "ST" >> return (TimeZone ((-8) * 60) False "PST")
116 , string "DT" >> return (TimeZone ((-7) * 60) True "PDT")
118 , char 'Z' >> return (TimeZone 0 False "Z")
119 , char 'A' >> return (TimeZone ((-1) * 60) False "A")
120 , char 'N' >> return (TimeZone ( 1 * 60) False "N")
121 , char 'Y' >> return (TimeZone ( 12 * 60) False "Y")
122 , do sign <- (char '+' >> return 1)
124 (char '-' >> return (-1))
128 timeZoneMinutes = (sign * (hour * 60 + minute))
129 , timeZoneSummerOnly = False
130 , timeZoneName = timeZoneOffsetString tz