1 -- |This module parses and prints RFC 1123 Date and Time string.
3 -- In general you don't have to use this module directly.
4 module Network.HTTP.Lucu.RFC1123DateTime
5 ( formatRFC1123DateTime
12 import Data.ByteString.Base (LazyByteString)
13 import Network.HTTP.Lucu.Format
14 import Network.HTTP.Lucu.Parser
18 month = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
21 week = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]
23 -- |Format a 'System.Time.CalendarTime' to RFC 1123 Date and Time
25 formatRFC1123DateTime :: CalendarTime -> String
26 formatRFC1123DateTime time
29 id (week !! fromEnum (ctWDay time))
33 id (month !! fromEnum (ctMonth time))
35 fmtDec 4 (ctYear time)
37 fmtDec 2 (ctHour time)
46 -- |Format a 'System.Time.ClockTime' to HTTP Date and Time. Time zone
47 -- will be always UTC but prints as GMT.
48 formatHTTPDateTime :: ClockTime -> String
49 formatHTTPDateTime time
51 formatRFC1123DateTime $! (\cal -> cal { ctTZName = "GMT" }) $! toUTCTime time
53 -- |Parse an HTTP Date and Time.
55 -- Limitation: RFC 2616 (HTTP\/1.1) says we must accept these three
58 -- * @Sun, 06 Nov 1994 08:49:37 GMT ; RFC 822, updated by RFC 1123@
60 -- * @Sunday, 06-Nov-94 08:49:37 GMT ; RFC 850, obsoleted by RFC 1036@
62 -- * @Sun Nov 6 08:49:37 1994 ; ANSI C's asctime() format@
64 -- ...but currently this function only supports the RFC 1123
65 -- format. This is a violation of RFC 2616 so this should be fixed
66 -- later. What a bother!
67 parseHTTPDateTime :: LazyByteString -> Maybe ClockTime
69 = case parse httpDateTime src of
70 (# Success ct, _ #) -> Just ct
71 (# _ , _ #) -> Nothing
74 httpDateTime :: Parser ClockTime
75 httpDateTime = do foldl (<|>) failP (map string week)
78 day <- liftM read (count 2 digit)
80 mon <- foldl (<|>) failP (map tryEqToFst (zip month [1..]))
82 year <- liftM read (count 4 digit)
84 hour <- liftM read (count 2 digit)
86 min <- liftM read (count 2 digit)
88 sec <- liftM read (count 2 digit)
92 return $ toClockTime $ CalendarTime {
94 , ctMonth = toEnum (mon - 1)
103 , ctTZName = undefined
104 , ctIsDST = undefined
107 tryEqToFst :: (String, a) -> Parser a
108 tryEqToFst (str, a) = string str >> return a