+
+-- |Pad a string on the left with zeros until the entire string has
+-- length n.
+pad_left :: String -> Int -> String
+pad_left str n
+ | n < (length str) = str
+ | otherwise = (replicate num_zeros '0') ++ str
+ where num_zeros = n - (length str)
+
+
+
+-- |Formats a month name according to RFC822.
+format_month :: Month -> String
+format_month month = take 3 (show month)
+
+
+-- |Takes an offset from UTC (in seconds) and returns the four-digit
+-- offset as a 'String' in +hhmm format.
+format_timezone :: Int -> String
+format_timezone seconds =
+ sign ++ pad_hh ++ pad_mm
+ where
+ seconds_norm = abs seconds
+ hh = seconds_norm `div` 3600
+ mm = (seconds_norm - (hh*3600)) `div` 60
+ pad_hh = pad_left (show hh) 2
+ pad_mm = pad_left (show mm) 2
+ sign = if seconds < 0 then "-" else "+"
+
+
+-- |Takes a 'ClockTime' as an argument, and formats it as an RFC822 Date header.
+--
+-- See,
+--
+-- <http://cr.yp.to/immhf/date.html>
+--
+-- for information.
+format_clocktime :: ClockTime -> IO String
+format_clocktime ct = do
+ caltime <- (toCalendarTime ct)
+
+ let days = pad_left (show (ctDay caltime)) 2
+ let month = format_month (ctMonth caltime)
+ let year = show $ ctYear caltime
+ let hours = pad_left (show (ctHour caltime)) 2
+ let minutes = pad_left (show (ctMin caltime)) 2
+ let seconds = pad_left (show (ctSec caltime)) 2
+ let timezone = format_timezone (ctTZ caltime)
+
+ return $ concat [(show $ ctWDay caltime) ++ ", ",
+ days ++ " ",
+ month ++ " ",
+ year ++ " ",
+ hours ++ ":",
+ minutes ++ ":",
+ seconds ++ " ",
+ timezone]
+
+
+-- |Constructs an RFC822 Date header with the current date/time.
+construct_date_header :: IO String
+construct_date_header = do
+ date <- getClockTime
+ format_clocktime date
+
+
+