3 , MultiParamTypeClasses
8 -- |This module provides functions to parse and format RFC 1123 date
9 -- and time strings (<http://tools.ietf.org/html/rfc1123#page-55>).
11 -- The format is basically the same as RFC 822, but the syntax for
12 -- @date@ is changed from:
19 module Data.Time.Format.RFC1123
24 import Control.Applicative
25 import Data.Ascii (Ascii, AsciiBuilder)
26 import qualified Data.Ascii as A
27 import Data.Attoparsec.Char8
28 import Data.Convertible.Base
29 import Data.Monoid.Unicode
32 import Data.Time.Calendar.WeekDate
33 import Data.Time.Format.HTTP.Common
34 import Data.Time.Format.RFC822.Internal
35 import Prelude.Unicode
37 -- |The phantom type for conversions between RFC 1123 date and time
38 -- strings and 'ZonedTime'.
40 -- >>> convertSuccess (ZonedTime (LocalTime (ModifiedJulianDay 49662) (TimeOfDay 8 49 37)) utc)
41 -- Tagged "Sun, 06 Nov 1994 08:49:37 GMT"
44 instance ConvertSuccess ZonedTime (Tagged RFC1123 Ascii) where
45 {-# INLINE convertSuccess #-}
46 convertSuccess = (A.fromAsciiBuilder <$>) ∘ cs
48 instance ConvertSuccess ZonedTime (Tagged RFC1123 AsciiBuilder) where
49 {-# INLINE convertSuccess #-}
50 convertSuccess = Tagged ∘ toAsciiBuilder
52 instance ConvertAttempt (Tagged RFC1123 Ascii) ZonedTime where
53 {-# INLINE convertAttempt #-}
54 convertAttempt = parseAttempt' rfc1123DateAndTime ∘ untag
56 -- |Parse an RFC 1123 date and time string.
57 rfc1123DateAndTime ∷ Parser ZonedTime
58 rfc1123DateAndTime = dateTime
60 dateTime ∷ Parser ZonedTime
61 dateTime = do weekDay ← optionMaybe $
62 do w ← shortWeekDayNameP
70 → assertWeekDayIsGood givenWD gregDay
71 (tod, timeZone) ← rfc822Time
72 let lt = LocalTime gregDay tod
73 zt = ZonedTime lt timeZone
79 month ← shortMonthNameP
83 assertGregorianDateIsGood year month day
85 toAsciiBuilder ∷ ZonedTime → AsciiBuilder
86 toAsciiBuilder zonedTime
87 = let localTime = zonedTimeToLocalTime zonedTime
88 timeZone = zonedTimeZone zonedTime
89 (year, month, day) = toGregorian (localDay localTime)
90 (_, _, week) = toWeekDate (localDay localTime)
91 timeOfDay = localTimeOfDay localTime
94 ⊕ A.toAsciiBuilder ", "
96 ⊕ A.toAsciiBuilder " "
97 ⊕ shortMonthName month
98 ⊕ A.toAsciiBuilder " "
100 ⊕ A.toAsciiBuilder " "
101 ⊕ show2 (todHour timeOfDay)
102 ⊕ A.toAsciiBuilder ":"
103 ⊕ show2 (todMin timeOfDay)
104 ⊕ A.toAsciiBuilder ":"
105 ⊕ show2 (floor (todSec timeOfDay) ∷ Int)
106 ⊕ A.toAsciiBuilder " "
107 ⊕ untag (cs timeZone ∷ Tagged RFC822 AsciiBuilder)
109 deriveAttempts [ ([t| ZonedTime |], [t| Tagged RFC1123 Ascii |])
110 , ([t| ZonedTime |], [t| Tagged RFC1123 AsciiBuilder |])