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
25 import Control.Applicative
26 import Data.Ascii (Ascii, AsciiBuilder)
27 import qualified Data.Ascii as A
28 import Data.Attoparsec.Char8
29 import Data.Convertible.Base
30 import Data.Monoid.Unicode
34 import Data.Time.Calendar.WeekDate
35 import Data.Time.Format.HTTP.Common
36 import Data.Time.Format.RFC822.Internal
37 import Prelude.Unicode
39 -- |The phantom type for conversions between RFC 1123 date and time
40 -- strings and 'ZonedTime'.
42 -- >>> convertSuccess (ZonedTime (LocalTime (ModifiedJulianDay 49662) (TimeOfDay 8 49 37)) utc)
43 -- Tagged "Sun, 06 Nov 1994 08:49:37 GMT"
46 -- |The proxy for conversions between RFC 1123 date and time strings
48 rfc1123 ∷ Proxy RFC1123
49 {-# INLINE CONLIKE rfc1123 #-}
52 instance ConvertSuccess ZonedTime (Tagged RFC1123 Ascii) where
53 {-# INLINE convertSuccess #-}
54 convertSuccess = (A.fromAsciiBuilder <$>) ∘ cs
56 instance ConvertSuccess ZonedTime (Tagged RFC1123 AsciiBuilder) where
57 {-# INLINE convertSuccess #-}
58 convertSuccess = Tagged ∘ toAsciiBuilder
60 instance ConvertAttempt (Tagged RFC1123 Ascii) ZonedTime where
61 {-# INLINE convertAttempt #-}
62 convertAttempt = parseAttempt' rfc1123DateAndTime ∘ untag
64 -- |Parse an RFC 1123 date and time string.
65 rfc1123DateAndTime ∷ Parser ZonedTime
66 rfc1123DateAndTime = dateTime
68 dateTime ∷ Parser ZonedTime
69 dateTime = do weekDay ← optionMaybe $
70 do w ← shortWeekDayNameP
78 → assertWeekDayIsGood givenWD gregDay
79 (tod, timeZone) ← rfc822Time
80 let lt = LocalTime gregDay tod
81 zt = ZonedTime lt timeZone
87 month ← shortMonthNameP
91 assertGregorianDateIsGood year month day
93 toAsciiBuilder ∷ ZonedTime → AsciiBuilder
94 toAsciiBuilder zonedTime
95 = let localTime = zonedTimeToLocalTime zonedTime
96 timeZone = zonedTimeZone zonedTime
97 (year, month, day) = toGregorian (localDay localTime)
98 (_, _, week) = toWeekDate (localDay localTime)
99 timeOfDay = localTimeOfDay localTime
101 shortWeekDayName week
102 ⊕ A.toAsciiBuilder ", "
104 ⊕ A.toAsciiBuilder " "
105 ⊕ shortMonthName month
106 ⊕ A.toAsciiBuilder " "
108 ⊕ A.toAsciiBuilder " "
109 ⊕ show2 (todHour timeOfDay)
110 ⊕ A.toAsciiBuilder ":"
111 ⊕ show2 (todMin timeOfDay)
112 ⊕ A.toAsciiBuilder ":"
113 ⊕ show2 (floor (todSec timeOfDay) ∷ Int)
114 ⊕ A.toAsciiBuilder " "
115 ⊕ untag (cs timeZone ∷ Tagged RFC822 AsciiBuilder)
117 deriveAttempts [ ([t| ZonedTime |], [t| Tagged RFC1123 Ascii |])
118 , ([t| ZonedTime |], [t| Tagged RFC1123 AsciiBuilder |])