|
Packit |
9a2dfb |
module Data.Aeson.Parser.Time
|
|
Packit |
9a2dfb |
(
|
|
Packit |
9a2dfb |
run
|
|
Packit |
9a2dfb |
, day
|
|
Packit |
9a2dfb |
, localTime
|
|
Packit |
9a2dfb |
, timeOfDay
|
|
Packit |
9a2dfb |
, timeZone
|
|
Packit |
9a2dfb |
, utcTime
|
|
Packit |
9a2dfb |
, zonedTime
|
|
Packit |
9a2dfb |
) where
|
|
Packit |
9a2dfb |
|
|
Packit |
9a2dfb |
import Prelude ()
|
|
Packit |
9a2dfb |
import Prelude.Compat
|
|
Packit |
9a2dfb |
|
|
Packit |
9a2dfb |
import Data.Attoparsec.Text (Parser)
|
|
Packit |
9a2dfb |
import Data.Text (Text)
|
|
Packit |
9a2dfb |
import Data.Time.Calendar (Day)
|
|
Packit |
9a2dfb |
import Data.Time.Clock (UTCTime(..))
|
|
Packit |
9a2dfb |
import qualified Data.Aeson.Types.Internal as Aeson
|
|
Packit |
9a2dfb |
import qualified Data.Attoparsec.Text as A
|
|
Packit |
9a2dfb |
import qualified Data.Attoparsec.Time as T
|
|
Packit |
9a2dfb |
import qualified Data.Time.LocalTime as Local
|
|
Packit |
9a2dfb |
|
|
Packit |
9a2dfb |
-- | Run an attoparsec parser as an aeson parser.
|
|
Packit |
9a2dfb |
run :: Parser a -> Text -> Aeson.Parser a
|
|
Packit |
9a2dfb |
run p t = case A.parseOnly (p <* A.endOfInput) t of
|
|
Packit |
9a2dfb |
Left err -> fail $ "could not parse date: " ++ err
|
|
Packit |
9a2dfb |
Right r -> return r
|
|
Packit |
9a2dfb |
|
|
Packit |
9a2dfb |
-- | Parse a date of the form @[+,-]YYYY-MM-DD@.
|
|
Packit |
9a2dfb |
day :: Parser Day
|
|
Packit |
9a2dfb |
day = T.day
|
|
Packit |
9a2dfb |
{-# INLINE day #-}
|
|
Packit |
9a2dfb |
|
|
Packit |
9a2dfb |
-- | Parse a time of the form @HH:MM[:SS[.SSS]]@.
|
|
Packit |
9a2dfb |
timeOfDay :: Parser Local.TimeOfDay
|
|
Packit |
9a2dfb |
timeOfDay = T.timeOfDay
|
|
Packit |
9a2dfb |
{-# INLINE timeOfDay #-}
|
|
Packit |
9a2dfb |
|
|
Packit |
9a2dfb |
-- | Parse a time zone, and return 'Nothing' if the offset from UTC is
|
|
Packit |
9a2dfb |
-- zero. (This makes some speedups possible.)
|
|
Packit |
9a2dfb |
timeZone :: Parser (Maybe Local.TimeZone)
|
|
Packit |
9a2dfb |
timeZone = T.timeZone
|
|
Packit |
9a2dfb |
{-# INLINE timeZone #-}
|
|
Packit |
9a2dfb |
|
|
Packit |
9a2dfb |
-- | Parse a date and time, of the form @YYYY-MM-DD HH:MM[:SS[.SSS]]@.
|
|
Packit |
9a2dfb |
-- The space may be replaced with a @T@. The number of seconds is optional
|
|
Packit |
9a2dfb |
-- and may be followed by a fractional component.
|
|
Packit |
9a2dfb |
localTime :: Parser Local.LocalTime
|
|
Packit |
9a2dfb |
localTime = T.localTime
|
|
Packit |
9a2dfb |
{-# INLINE localTime #-}
|
|
Packit |
9a2dfb |
|
|
Packit |
9a2dfb |
-- | Behaves as 'zonedTime', but converts any time zone offset into a
|
|
Packit |
9a2dfb |
-- UTC time.
|
|
Packit |
9a2dfb |
utcTime :: Parser UTCTime
|
|
Packit |
9a2dfb |
utcTime = T.utcTime
|
|
Packit |
9a2dfb |
{-# INLINE utcTime #-}
|
|
Packit |
9a2dfb |
|
|
Packit |
9a2dfb |
-- | Parse a date with time zone info. Acceptable formats:
|
|
Packit |
9a2dfb |
--
|
|
Packit |
9a2dfb |
-- @YYYY-MM-DD HH:MM Z@
|
|
Packit |
9a2dfb |
-- @YYYY-MM-DD HH:MM:SS Z@
|
|
Packit |
9a2dfb |
-- @YYYY-MM-DD HH:MM:SS.SSS Z@
|
|
Packit |
9a2dfb |
--
|
|
Packit |
9a2dfb |
-- The first space may instead be a @T@, and the second space is
|
|
Packit |
9a2dfb |
-- optional. The @Z@ represents UTC. The @Z@ may be replaced with a
|
|
Packit |
9a2dfb |
-- time zone offset of the form @+0000@ or @-08:00@, where the first
|
|
Packit |
9a2dfb |
-- two digits are hours, the @:@ is optional and the second two digits
|
|
Packit |
9a2dfb |
-- (also optional) are minutes.
|
|
Packit |
9a2dfb |
zonedTime :: Parser Local.ZonedTime
|
|
Packit |
9a2dfb |
zonedTime = T.zonedTime
|
|
Packit |
9a2dfb |
{-# INLINE zonedTime #-}
|