]> gitweb @ CieloNegro.org - time-http.git/blobdiff - Data/Time/RFC733/Internal.hs
Changed some module's name
[time-http.git] / Data / Time / RFC733 / Internal.hs
diff --git a/Data/Time/RFC733/Internal.hs b/Data/Time/RFC733/Internal.hs
new file mode 100644 (file)
index 0000000..5002655
--- /dev/null
@@ -0,0 +1,105 @@
+{-# LANGUAGE FlexibleContexts #-}
+module Data.Time.RFC733.Internal
+    ( rfc733DateAndTime
+    )
+    where
+import Control.Monad
+import Data.Fixed
+import Data.Time
+import Data.Time.Calendar.WeekDate
+import Data.Time.HTTP.Common
+
+-- |This is a parsec parser for RFC 733 date and time strings.
+rfc733DateAndTime :: Stream s m Char => ParsecT s u m ZonedTime
+rfc733DateAndTime = dateTime
+
+dateTime :: Stream s m Char => ParsecT s u m ZonedTime
+dateTime = do weekDay <- optionMaybe $
+                         do w <- try longWeekDayNameP
+                                 <|>
+                                 shortWeekDayNameP
+                            _ <- string ", "
+                            return w
+              gregDay <- date
+              case weekDay of
+                Nothing
+                    -> return ()
+                Just givenWD
+                    -> assertWeekDayIsGood givenWD gregDay
+              (tod, timeZone) <- time
+              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 '-' <|> char ' '
+          month <- try longMonthNameP
+                   <|>
+                   shortMonthNameP
+          _     <- char '-' <|> char ' '
+          year  <- try read4
+                   <|>
+                   liftM (+ 1900) read2
+          _     <- char ' '
+          assertGregorianDateIsGood year month day
+
+time :: Stream s m Char => ParsecT s u m (TimeOfDay, TimeZone)
+time = do tod <- hour
+          _   <- char '-' <|> char ' '
+          tz  <- zone
+          return (tod, tz)
+
+hour :: Stream s m Char => ParsecT s u m TimeOfDay
+hour = do hour   <- read2
+          _      <- optional (char ':')
+          minute <- read2
+          second <- option 0 $
+                    do _ <- optional (char ':')
+                       read2
+          assertTimeOfDayIsGood hour minute second
+
+zone :: Stream s m Char => ParsecT s u m TimeZone
+zone = choice [ string "GMT" >> return (TimeZone 0 False "GMT")
+              , char 'N'
+                >> choice [ string "ST" >> return (TimeZone ((-3) * 60 - 30) False "NST")
+                          , return (TimeZone (1 * 60) False "N")
+                          ]
+              , char 'A'
+                >> choice [ string "ST" >> return (TimeZone ((-4) * 60) False "AST")
+                          , string "DT" >> return (TimeZone ((-3) * 60) False "AST")
+                          , return (TimeZone ((-1) * 60) False "A")
+                          ]
+              , char 'E'
+                >> choice [ string "ST" >> return (TimeZone ((-5) * 60) False "EST")
+                          , string "DT" >> return (TimeZone ((-4) * 60) True  "EDT")
+                          ]
+              , char 'C'
+                >> choice [ string "ST" >> return (TimeZone ((-6) * 60) False "CST")
+                          , string "DT" >> return (TimeZone ((-5) * 60) True  "CDT")
+                          ]
+              , char 'M'
+                >> choice [ string "ST" >> return (TimeZone ((-7) * 60) False "MST")
+                          , string "DT" >> return (TimeZone ((-6) * 60) True  "MDT")
+                          , return (TimeZone ((-12) * 60) False "M")
+                          ]
+              , char 'P'
+                >> choice [ string "ST" >> return (TimeZone ((-8) * 60) False "PST")
+                          , string "DT" >> return (TimeZone ((-7) * 60) True  "PDT")
+                          ]
+              , char 'Y'
+                >> choice [ string "ST" >> return (TimeZone ((-9) * 60) False "YST")
+                          , string "DT" >> return (TimeZone ((-8) * 60) True  "YDT")
+                          , return (TimeZone ( 12  * 60) False "Y")
+                          ]
+              , char 'H'
+                >> choice [ string "ST" >> return (TimeZone ((-10) * 60) False "HST")
+                          , string "DT" >> return (TimeZone (( -9) * 60) True  "HDT")
+                          ]
+              , char 'B'
+                >> choice [ string "ST" >> return (TimeZone ((-11) * 60) False "BST")
+                          , string "DT" >> return (TimeZone ((-10) * 60) True  "BDT")
+                          ]
+              , char 'Z' >> return (TimeZone 0 False "Z")
+              , read4digitsTZ
+              ]