]> gitweb @ CieloNegro.org - time-http.git/blob - Data/Time/RFC822.hs
Finished docs
[time-http.git] / Data / Time / RFC822.hs
1 {-# OPTIONS_HADDOCK prune #-}
2
3 -- |This module provides functions to parse and format RFC 822 date
4 -- and time formats.
5 --
6 -- The syntax is as follows:
7 --
8 -- > date-time   ::= [ day-of-week ", " ] date SP time SP zone
9 -- > day-of-week ::= "Mon" | "Tue" | "Wed" | "Thu"
10 -- >               | "Fri" | "Sat" | "Sun"
11 -- > date        ::= day SP month SP year
12 -- > day         ::= 2DIGIT
13 -- > year        ::= 2DIGIT             ; Yes, only 2 digits.
14 -- > month       ::= "Jan" | "Feb" | "Mar" | "Apr"
15 -- >               | "May" | "Jun" | "Jul" | "Aug"
16 -- >               | "Sep" | "Oct" | "Nov" | "Dec"
17 -- > time        ::= hour ":" minute [ ":" second ]
18 -- > hour        ::= 2DIGIT
19 -- > minute      ::= 2DIGIT
20 -- > second      ::= 2DIGIT
21 -- > zone        ::= "UT"  | "GMT"      ; Universal Time
22 -- >               | "EST" | "EDT"      ; Eastern : -5 / -4
23 -- >               | "CST" | "CDT"      ; Central : -6 / -5
24 -- >               | "MST" | "MDT"      ; Mountain: -7 / -6
25 -- >               | "PST" | "PDT"      ; Pacific : -8 / -7
26 -- >               | "Z"                ; UT
27 -- >               | "A"                ;  -1
28 -- >               | "M"                ; -12
29 -- >               | "N"                ;  +1
30 -- >               | "Y"                ; +12
31 -- >               | ("+" | "-") 4DIGIT ; Local diff: HHMM
32 module Data.Time.RFC822
33     ( format
34     , parse
35
36     -- private
37     , showRFC822TimeZone
38     )
39     where
40
41 import qualified Text.Parsec as P
42
43 import Data.Time
44 import Data.Time.Calendar.WeekDate
45 import Data.Time.HTTP.Common
46 import Data.Time.RFC822.Parsec
47
48 -- |Format a 'ZonedTime' in RFC 822.
49 format :: ZonedTime -> String
50 format zonedTime
51     = let localTime          = zonedTimeToLocalTime zonedTime
52           timeZone           = zonedTimeZone zonedTime
53           (year, month, day) = toGregorian (localDay localTime)
54           (_, _, week)       = toWeekDate  (localDay localTime)
55           timeOfDay          = localTimeOfDay localTime
56       in
57         concat [ shortWeekDayName week
58                , ", "
59                , show2 day
60                , " "
61                , shortMonthName month
62                , " "
63                , show2 (year `mod` 100)
64                , " "
65                , show2 (todHour timeOfDay)
66                , ":"
67                , show2 (todMin timeOfDay)
68                , ":"
69                , show2 (floor (todSec timeOfDay))
70                , " "
71                , showRFC822TimeZone timeZone
72                ]
73
74 showRFC822TimeZone :: TimeZone -> String
75 showRFC822TimeZone tz
76     | timeZoneMinutes tz == 0 = "GMT"
77     | otherwise               = show4digitsTZ tz
78
79 -- |Parse an RFC 822 date and time string. When the string can't be
80 -- parsed, it returns 'Nothing'.
81 parse :: String -> Maybe ZonedTime
82 parse src = case P.parse p "" src of
83               Right zt -> Just zt
84               Left  _  -> Nothing
85     where
86       p = do zt <- rfc822DateAndTime
87              _  <- P.eof
88              return zt