3 , MultiParamTypeClasses
7 -- |This module provides functions for ANSI C's asctime() format.
9 -- ANSI C's asctime() format looks like:
11 -- @Wdy Mon [D]D HH:MM:SS YYYY@
13 -- The exact syntax is as follows:
15 -- > date-time ::= wday SP month SP day SP time SP year
16 -- > wday ::= "Mon" | "Tue" | "Wed" | "Thu"
17 -- > | "Fri" | "Sat" | "Sun"
18 -- > month ::= "Jan" | "Feb" | "Mar" | "Apr"
19 -- > | "May" | "Jun" | "Jul" | "Aug"
20 -- > | "Sep" | "Oct" | "Nov" | "Dec"
21 -- > day ::= 2DIGIT | SP 1DIGIT
22 -- > time ::= 2DIGIT ':' 2DIGIT [':' 2DIGIT]
25 -- As you can see, it has no time zone info. "Data.Time.HTTP" will
27 module Data.Time.Asctime
32 import Control.Applicative
33 import Data.Ascii (Ascii, AsciiBuilder)
34 import qualified Data.Ascii as A
35 import Data.Attoparsec.Char8
36 import Data.Convertible.Base
37 import Data.Monoid.Unicode
40 import Data.Time.Calendar.WeekDate
41 import Data.Time.HTTP.Common
42 import Prelude.Unicode
44 -- |The phantom type for conversion between ANSI C's @asctime()@
45 -- string and 'LocalTime'.
47 -- >>> convertSuccess (LocalTime (ModifiedJulianDay 49662) (TimeOfDay 8 49 37))
48 -- Tagged "Sun Nov 6 08:49:37 1994"
51 instance ConvertSuccess LocalTime (Tagged Asctime Ascii) where
52 {-# INLINE convertSuccess #-}
53 convertSuccess = (A.fromAsciiBuilder <$>) ∘ cs
55 instance ConvertAttempt LocalTime (Tagged Asctime Ascii) where
56 {-# INLINE convertAttempt #-}
57 convertAttempt = return ∘ cs
59 instance ConvertSuccess LocalTime (Tagged Asctime AsciiBuilder) where
60 {-# INLINE convertSuccess #-}
61 convertSuccess = Tagged ∘ toAsciiBuilder
63 instance ConvertAttempt LocalTime (Tagged Asctime AsciiBuilder) where
64 {-# INLINE convertAttempt #-}
65 convertAttempt = return ∘ cs
67 instance ConvertAttempt (Tagged Asctime Ascii) LocalTime where
68 {-# INLINE convertAttempt #-}
69 convertAttempt = parseAttempt' asctime ∘ untag
71 -- |Parse an ANSI C's @asctime()@ string.
72 asctime ∷ Parser LocalTime
73 asctime = do weekDay ← shortWeekDayNameP
75 month ← shortMonthNameP
87 gregDay ← assertGregorianDateIsGood year month day
88 _ ← assertWeekDayIsGood weekDay gregDay
89 tod ← assertTimeOfDayIsGood hour minute second
91 return (LocalTime gregDay tod)
93 toAsciiBuilder ∷ LocalTime → AsciiBuilder
94 toAsciiBuilder localTime
95 = let (year, month, day) = toGregorian (localDay localTime)
96 (_, _, week) = toWeekDate (localDay localTime)
97 timeOfDay = localTimeOfDay localTime
100 ⊕ A.toAsciiBuilder " "
101 ⊕ shortMonthName month
102 ⊕ A.toAsciiBuilder " "
104 ⊕ A.toAsciiBuilder " "
105 ⊕ show2 (todHour timeOfDay)
106 ⊕ A.toAsciiBuilder ":"
107 ⊕ show2 (todMin timeOfDay)
108 ⊕ A.toAsciiBuilder ":"
109 ⊕ show2 (floor (todSec timeOfDay) ∷ Int)
110 ⊕ A.toAsciiBuilder " "