]> gitweb @ CieloNegro.org - time-http.git/blob - Data/Time/HTTP.hs
Data.Time.HTTP now compiles.
[time-http.git] / Data / Time / HTTP.hs
1 {-# LANGUAGE
2     UnicodeSyntax
3   #-}
4 -- |This module provides functions to parse and format HTTP\/1.1 date
5 -- and time formats.
6 --
7 -- The HTTP\/1.1 specification (RFC 2616) says that HTTP\/1.1 clients
8 -- and servers which parse the date value MUST accept all the
9 -- following formats, though they MUST only generate the RFC 1123
10 -- format for representing HTTP-date values in header fields:
11 --
12 -- > Sun, 06 Nov 1994 08:49:37 GMT  ; RFC 822, updated by RFC 1123
13 -- > Sunday, 06-Nov-94 08:49:37 GMT ; RFC 850, obsoleted by RFC 1036
14 -- > Sun Nov  6 08:49:37 1994       ; ANSI C's asctime() format
15 --
16 -- It also says that all HTTP date\/time stamps MUST be represented in
17 -- Greenwich Mean Time (GMT), without exception. For the purposes of
18 -- HTTP, GMT is exactly equal to UTC (Coordinated Universal
19 -- Time). This is indicated in the first two formats by the inclusion
20 -- of @\"GMT\"@ as the three-letter abbreviation for time zone, and
21 -- MUST be assumed when reading the asctime format.
22 --
23 -- > HTTP-date    = rfc1123-date | rfc850-date | asctime-date
24 -- > rfc1123-date = wkday "," SP date1 SP time SP "GMT"
25 -- > rfc850-date  = weekday "," SP date2 SP time SP "GMT"
26 -- > asctime-date = wkday SP date3 SP time SP 4DIGIT
27 -- > date1        = 2DIGIT SP month SP 4DIGIT
28 -- >                ; day month year (e.g., 02 Jun 1982)
29 -- > date2        = 2DIGIT "-" month "-" 2DIGIT
30 -- >                ; day-month-year (e.g., 02-Jun-82)
31 -- > date3        = month SP ( 2DIGIT | ( SP 1DIGIT ))
32 -- >                ; month day (e.g., Jun  2)
33 -- > time         = 2DIGIT ":" 2DIGIT ":" 2DIGIT
34 -- >                ; 00:00:00 - 23:59:59
35 -- > wkday        = "Mon" | "Tue" | "Wed"
36 -- >              | "Thu" | "Fri" | "Sat" | "Sun"
37 -- > weekday      = "Monday" | "Tuesday" | "Wednesday"
38 -- >              | "Thursday" | "Friday" | "Saturday" | "Sunday"
39 -- > month        = "Jan" | "Feb" | "Mar" | "Apr"
40 -- >              | "May" | "Jun" | "Jul" | "Aug"
41 -- >              | "Sep" | "Oct" | "Nov" | "Dec"
42 module Data.Time.HTTP
43     ( -- * Formatting
44       toAscii
45     , toAsciiBuilder
46
47       -- * Parsing
48     , fromAscii
49     , httpDateAndTime
50     )
51     where
52 import Data.Ascii (Ascii)
53 import qualified Data.Ascii as A
54 import qualified Data.Attoparsec.Char8 as P
55 import Data.Time
56 import Data.Time.HTTP.Internal
57 import Prelude.Unicode
58
59 -- |Convert a 'UTCTime' to RFC 1123 date and time string.
60 toAscii ∷ UTCTime → Ascii
61 toAscii = A.fromAsciiBuilder ∘ toAsciiBuilder
62
63 -- |Parse a date and time string in any of RFC 822, RFC 1123, RFC 850
64 -- and ANSI C's asctime() formats. When the string can't be parsed, it
65 -- returns @'Left' err@.
66 --
67 -- This function is even more permissive than what HTTP\/1.1
68 -- specifies. That is, it accepts 2-digit years in RFC 822, omitted
69 -- separator symbols in RFC 850, omitted sec fields, and non-GMT time
70 -- zones. I believe this behavior will not cause a problem but you
71 -- should know this.
72 fromAscii ∷ Ascii → Either String UTCTime
73 fromAscii = P.parseOnly p ∘ A.toByteString
74     where
75       p = do zt ← httpDateAndTime
76              P.endOfInput
77              return zt