[Parsers for HTTP dates (RFC 1123, RFC 850, ANSI C). Minimal tests to match. prb@mult.ifario.us**20080229184146] { hunk ./src/Utilities.hs 3 - , iso8601toRfc1123, rfc1123toIso8601 ) where + , iso8601toRfc1123, httpDateToIso8601 ) where hunk ./src/Utilities.hs 191 -rfc1123toIso8601 d = case P.parse rfc1123DateParser "" d of - Left _ -> - "" - Right d' -> - d' +rfc1123toIso8601 d = case P.parse rfc1123DateParser d d of + Left _ -> "" + Right d' -> d' + +httpDateToIso8601 :: String -> String +httpDateToIso8601 d = case P.parse httpDateParser d d of + Left e -> show e + Right d' -> d' + +httpDateParser :: P.Parser String +httpDateParser = (try rfc1123DateParser) + <|> (try rfc850DateParser) <|> ansiDateParser + +ansiDateParser :: P.Parser String +ansiDateParser = do { short_day + ; space + ; month <- short_month + ; space + ; spaces + ; day <- many1 digit + ; space + ; t <- hms + ; space + ; year <- count 4 digit + ; return $ concat [ year, "-", (zpad $ show month), "-", zpad day, "T" + , t, "Z" ] } + +rfc850DateParser :: P.Parser String +rfc850DateParser = do { long_day + ; string ", " + ; day <- count 2 digit + ; char '-' + ; month <- short_month + ; char '-' + ; year <- count 2 digit + ; space + ; t <- hms + ; string " GMT" + ; return $ concat [ "20", year, "-", (zpad $ show month), "-", day, "T" + , t, "Z" ] } hunk ./src/Utilities.hs 233 -rfc1123DateParser = do { P.choice $ map P.string [ "Sun", "Mon", "Tue", "Wed", "Thu" - , "Fri","Sat","Sun"] +rfc1123DateParser = do { short_day hunk ./src/Utilities.hs 237 - ; month <- P.choice $ map (\(n,s) -> P.string s >> return n) - $ zip [1..12] [ "Jan", "Feb", "Mar", "Apr", "May", "Jun" - , "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ] + ; month <- short_month hunk ./src/Utilities.hs 241 - ; hour <- count 2 digit - ; char ':' - ; minute <- count 2 digit - ; char ':' - ; seconds <- count 2 digit + ; t <- hms hunk ./src/Utilities.hs 244 - , hour, ":", minute, ":", seconds, "Z" ] } + , t, "Z" ] } + +hms :: P.Parser String +hms = do { hour <- count 2 digit + ; char ':' + ; minute <- count 2 digit + ; char ':' + ; seconds <- count 2 digit + ; return $ concat [ hour, ':':minute, ':':seconds ]} + +long_day :: P.Parser String +long_day = (P.choice $ map (try . P.string) [ "Sunday", "Monday", "Tuesday", "Wednesday" + , "Thursday", "Friday", "Saturday" ]) + +short_day :: P.Parser String +short_day = P.choice $ map (try . P.string) [ "Sun", "Mon", "Tue", "Wed", "Thu" + , "Fri","Sat" ] hunk ./src/Utilities.hs 262 +short_month :: P.Parser Int +short_month = P.choice $ map (\(n,s) -> P.string s >> return n) + $ zip [1..12] [ "Jan", "Feb", "Mar", "Apr", "May", "Jun" + , "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ] addfile ./test.sh hunk ./test.sh 1 - +#!/bin/bash +cd testsrc +ghc --make -i../src runtests.hs +./runtests hunk ./testsrc/UtilitiesTests.hs 10 - , testTimeFormatting ] + , testTimeFormatting + , testTimestampTransformations ] hunk ./testsrc/UtilitiesTests.hs 66 - "delimiters when padded" ~: "--T::Z" ~?= [f!!4,f!!7,f!!10,f!!13,f!!16,f!!19] - , "delimiters when unpadded" ~: "--T::Z" ~?= [g!!4,g!!7,g!!10,g!!13,g!!16,g!!19] + "delimiters when padded" ~: "--T::Z" ~=? [f!!4,f!!7,f!!10,f!!13,f!!16,f!!19] + , "delimiters when unpadded" ~: "--T::Z" ~=? [g!!4,g!!7,g!!10,g!!13,g!!16,g!!19] hunk ./testsrc/UtilitiesTests.hs 90 +testTimestampTransformations = test [ + -- check ISO 8601 -> RFC 1123 + "Conversion of a date/time without padded entries" ~: (U.iso8601toRfc1123 "2008-02-29T21:47:30Z") ~?= "Fri, 29 Feb 2008 21:47:30 GMT" + , "Conversion of a date/time with padded entries" ~: (U.iso8601toRfc1123 "2008-02-08T01:07:00Z") ~?= "Fri, 08 Feb 2008 01:07:00 GMT" + -- check RFC 1123 -> ISO 8601 + , "Conversion of RFC 1123 to ISO 8601" ~: (U.httpDateToIso8601 "Thu, 29 Feb 2008 21:47:30 GMT") ~?= "2008-02-29T21:47:30Z" + -- check RFC 850 -> ISO 8601 + , "Conversion of RFC 850 to ISO 8601" ~: (U.httpDateToIso8601 "Thursday, 29-Feb-08 21:47:30 GMT") ~?= "2008-02-29T21:47:30Z" + -- check ANSI C -> ISO 8601 + , "Conversion of ANSI C to ISO 8601" ~: (U.httpDateToIso8601 "Thu Feb 29 21:47:30 2008") ~?= "2008-02-29T21:47:30Z" + ] }