X-Git-Url: http://git.cielonegro.org/gitweb.cgi?p=time-http.git;a=blobdiff_plain;f=Data%2FTime%2FHTTP%2FCommon.hs;h=e0a899e6c7e801d4dc4f18d601635aaab4dfa272;hp=1ea61de90bc2a21cc0e85a5d41fe63225d188a34;hb=82afb594c5b4254385435491700befcbea185a5d;hpb=9f9ed0471883b50fec1b091621f332d62477a34c diff --git a/Data/Time/HTTP/Common.hs b/Data/Time/HTTP/Common.hs index 1ea61de..e0a899e 100644 --- a/Data/Time/HTTP/Common.hs +++ b/Data/Time/HTTP/Common.hs @@ -9,16 +9,27 @@ module Data.Time.HTTP.Common , shortMonthName , shortMonthNameP + , longMonthName + , longMonthNameP + , show2 , show4 , read2 , read4 + + , show4digitsTZ + , read4digitsTZ + + , assertWeekDayIsGood + , assertGregorianDateIsGood + , assertTimeOfDayIsGood ) where - import Control.Monad -import Text.Parsec +import Data.Fixed +import Data.Time +import Data.Time.Calendar.WeekDate shortWeekDayName :: Int -> String shortWeekDayName 1 = "Mon" @@ -108,17 +119,56 @@ shortMonthNameP , string "Dec" >> return 12 ] +longMonthName :: Int -> String +longMonthName 1 = "January" +longMonthName 2 = "February" +longMonthName 3 = "March" +longMonthName 4 = "April" +longMonthName 5 = "May" +longMonthName 6 = "June" +longMonthName 7 = "July" +longMonthName 8 = "August" +longMonthName 9 = "September" +longMonthName 10 = "October" +longMonthName 11 = "November" +longMonthName 12 = "December" +longMonthName n = error ("longMonthName: unknown month number: " ++ show n) + +longMonthNameP :: Stream s m Char => ParsecT s u m Int +longMonthNameP + = choice [ char 'J' + >> choice [ string "anuary" >> return 1 + , char 'u' + >> choice [ string "ne" >> return 6 + , string "ly" >> return 7 + ] + ] + , string "February" >> return 2 + , string "Ma" + >> choice [ string "rch" >> return 3 + , char 'y' >> return 5 + ] + , char 'A' + >> choice [ string "pril" >> return 4 + , string "ugust" >> return 8 + ] + , string "September" >> return 9 + , string "October" >> return 10 + , string "November" >> return 11 + , string "December" >> return 12 + ] + show4 :: Integral i => i -> String show4 i | i >= 0 && i < 10 = "000" ++ show i | i >= 0 && i < 100 = "00" ++ show i - | i >= 0 && i < 1000 = "0" ++ show i + | i >= 0 && i < 1000 = '0' : show i | i >= 0 && i < 10000 = show i | otherwise = error ("show4: the integer i must satisfy 0 <= i < 10000: " ++ show i) show2 :: Integral i => i -> String show2 i - | i >= 0 && i < 10 = "0" ++ show i + | i >= 0 && i < 10 = '0' : show i | i >= 0 && i < 100 = show i | otherwise = error ("show2: the integer i must satisfy 0 <= i < 100: " ++ show i) @@ -149,3 +199,76 @@ fromC '7' = 7 fromC '8' = 8 fromC '9' = 9 fromC _ = undefined + +show4digitsTZ :: TimeZone -> String +show4digitsTZ tz + = case timeZoneMinutes tz of + offset | offset < 0 -> '-' : showTZ' (negate offset) + | otherwise -> '+' : showTZ' offset + where + showTZ' offset + = let h = offset `div` 60 + m = offset - h * 60 + in + show2 h ++ show2 m + +read4digitsTZ :: Stream s m Char => ParsecT s u m TimeZone +read4digitsTZ + = do sign <- (char '+' >> return 1) + <|> + (char '-' >> return (-1)) + hour <- read2 + minute <- read2 + let tz = TimeZone { + timeZoneMinutes = sign * (hour * 60 + minute) + , timeZoneSummerOnly = False + , timeZoneName = timeZoneOffsetString tz + } + return tz + +assertWeekDayIsGood :: Stream s m t => Int -> Day -> ParsecT s u m () +assertWeekDayIsGood givenWD gregDay + = let (_, _, correctWD ) = toWeekDate gregDay + (year, month, day) = toGregorian gregDay + in + unless (givenWD == correctWD) + $ fail + $ concat [ "Gregorian day " + , show year + , "-" + , show month + , "-" + , show day + , " is " + , longWeekDayName correctWD + , ", not " + , longWeekDayName givenWD + ] + +assertGregorianDateIsGood :: Stream s m t => Integer -> Int -> Int -> ParsecT s u m Day +assertGregorianDateIsGood year month day + = case fromGregorianValid year month day of + Nothing + -> fail $ concat [ "Invalid gregorian day: " + , show year + , "-" + , show month + , "-" + , show day + ] + Just gregDay + -> return gregDay + +assertTimeOfDayIsGood :: Stream s m t => Int -> Int -> Pico -> ParsecT s u m TimeOfDay +assertTimeOfDayIsGood hour minute second + = case makeTimeOfDayValid hour minute second of + Nothing + -> fail $ concat [ "Invalid time of day: " + , show hour + , ":" + , show minute + , ":" + , showFixed True second + ] + Just tod + -> return tod