]> gitweb @ CieloNegro.org - time-http.git/blob - Data/Time/Asctime.hs
Delete Data.Time.Asctime.Internal
[time-http.git] / Data / Time / Asctime.hs
1 {-# LANGUAGE
2     OverloadedStrings
3   , UnicodeSyntax
4   #-}
5 -- |This module provides functions for ANSI C's asctime() format.
6 --
7 -- ANSI C's asctime() format looks like:
8 --
9 -- @Wdy Mon [D]D HH:MM:SS YYYY@
10 --
11 -- The exact syntax is as follows:
12 --
13 -- > date-time ::= wday SP month SP day SP time SP year
14 -- > wday      ::= "Mon" | "Tue" | "Wed" | "Thu"
15 -- >             | "Fri" | "Sat" | "Sun"
16 -- > month     ::= "Jan" | "Feb" | "Mar" | "Apr"
17 -- >             | "May" | "Jun" | "Jul" | "Aug"
18 -- >             | "Sep" | "Oct" | "Nov" | "Dec"
19 -- > day       ::= 2DIGIT | SP 1DIGIT
20 -- > time      ::= 2DIGIT ':' 2DIGIT [':' 2DIGIT]
21 -- > year      ::= 4DIGIT
22 --
23 -- As you can see, it has no time zone info. "Data.Time.HTTP" will
24 -- treat it as UTC.
25 module Data.Time.Asctime
26     ( -- * Formatting
27       toAscii
28     , toAsciiBuilder
29
30       -- * Parsing
31     , fromAscii
32     , asctime
33     )
34     where
35 import Data.Ascii (Ascii, AsciiBuilder)
36 import qualified Data.Ascii as A
37 import Data.Attoparsec.Char8
38 import Data.Monoid.Unicode
39 import Data.Time
40 import Data.Time.Calendar.WeekDate
41 import Data.Time.HTTP.Common
42 import Prelude.Unicode
43
44 -- |Convert a 'LocalTime' to ANSI C's @asctime()@ string.
45 toAscii ∷ LocalTime → Ascii
46 toAscii = A.fromAsciiBuilder ∘ toAsciiBuilder
47
48 -- |Parse an ANSI C's @asctime()@ string. When the string can't be
49 -- parsed, it returns @'Left' err@.
50 fromAscii ∷ Ascii → Either String LocalTime
51 fromAscii = parseOnly p ∘ A.toByteString
52     where
53       p = do zt ← asctime
54              endOfInput
55              return zt
56
57 -- |Parse an ANSI C's @asctime()@ string.
58 asctime ∷ Parser LocalTime
59 asctime = do weekDay ← shortWeekDayNameP
60              _       ← char ' '
61              month   ← shortMonthNameP
62              _       ← char ' '
63              day     ← read2'
64              _       ← char ' '
65              hour    ← read2
66              _       ← char ':'
67              minute  ← read2
68              _       ← char ':'
69              second  ← read2
70              _       ← char ' '
71              year    ← read4
72
73              gregDay ← assertGregorianDateIsGood year month day
74              _       ← assertWeekDayIsGood weekDay gregDay
75              tod     ← assertTimeOfDayIsGood hour minute second
76
77              return (LocalTime gregDay tod)
78
79 -- |Convert a 'LocalTime' to ANSI C's @asctime()@ string.
80 toAsciiBuilder ∷ LocalTime → AsciiBuilder
81 toAsciiBuilder localTime
82     = let (year, month, day) = toGregorian (localDay localTime)
83           (_, _, week)       = toWeekDate  (localDay localTime)
84           timeOfDay          = localTimeOfDay localTime
85       in
86         shortWeekDayName week
87         ⊕ A.toAsciiBuilder " "
88         ⊕ shortMonthName month
89         ⊕ A.toAsciiBuilder " "
90         ⊕ show2' day
91         ⊕ A.toAsciiBuilder " "
92         ⊕ show2 (todHour timeOfDay)
93         ⊕ A.toAsciiBuilder ":"
94         ⊕ show2 (todMin timeOfDay)
95         ⊕ A.toAsciiBuilder ":"
96         ⊕ show2 (floor (todSec timeOfDay) ∷ Int)
97         ⊕ A.toAsciiBuilder " "
98         ⊕ show4 year