module Data.Time.Format.Parse
(
parseTimeM
, parseTimeMultipleM
, parseTimeOrError
, readSTime
, readPTime
, ParseTime()
, module Data.Time.Format.Locale
) where
import Control.Applicative ((<|>))
import Control.Monad.Fail
import Data.Char
import Data.Proxy
import Data.Traversable
import Data.Time.Calendar.Days
import Data.Time.Clock.Internal.UTCTime
import Data.Time.Clock.Internal.UniversalTime
import Data.Time.Format.Locale
import Data.Time.Format.Parse.Class
import Data.Time.Format.Parse.Instances ()
import Data.Time.LocalTime.Internal.LocalTime
import Data.Time.LocalTime.Internal.TimeOfDay
import Data.Time.LocalTime.Internal.TimeZone
import Data.Time.LocalTime.Internal.ZonedTime
import Prelude hiding (fail)
import Text.ParserCombinators.ReadP hiding (char, string)
parseTimeM ::
(MonadFail m, ParseTime t)
=> Bool
-> TimeLocale
-> String
-> String
-> m t
parseTimeM acceptWS l fmt s = parseTimeMultipleM acceptWS l [(fmt, s)]
parseTimeMultipleM' ::
(MonadFail m, ParseTime t)
=> Proxy t
-> Bool
-> TimeLocale
-> [(String, String)]
-> m t
parseTimeMultipleM' pt acceptWS l fmts = do
specss <- for fmts $ \(fmt,s) -> parseTimeSpecifiersM pt acceptWS l fmt s
case buildTime l $ mconcat specss of
Just t -> return t
Nothing -> fail "parseTimeM: cannot construct"
parseTimeMultipleM ::
(MonadFail m, ParseTime t)
=> Bool
-> TimeLocale
-> [(String, String)]
-> m t
parseTimeMultipleM = parseTimeMultipleM' Proxy
parseTimeOrError ::
ParseTime t
=> Bool
-> TimeLocale
-> String
-> String
-> t
parseTimeOrError acceptWS l fmt s =
case parseTimeM acceptWS l fmt s of
[t] -> t
[] -> error $ "parseTimeOrError: no parse of " ++ show s
_ -> error $ "parseTimeOrError: multiple parses of " ++ show s
parseTimeSpecifiersM ::
(MonadFail m, ParseTime t)
=> Proxy t
-> Bool
-> TimeLocale
-> String
-> String
-> m [(Char, String)]
parseTimeSpecifiersM pt acceptWS l fmt s =
case parseTimeSpecifiers pt acceptWS l fmt s of
[t] -> return t
[] -> fail $ "parseTimeM: no parse of " ++ show s
_ -> fail $ "parseTimeM: multiple parses of " ++ show s
parseTimeSpecifiers ::
ParseTime t
=> Proxy t
-> Bool
-> TimeLocale
-> String
-> String
-> [[(Char, String)]]
parseTimeSpecifiers pt False l fmt s = [t | (t, "") <- readP_to_S (readPSpecifiers pt False l fmt) s]
parseTimeSpecifiers pt True l fmt s = [t | (t, r) <- readP_to_S (readPSpecifiers pt True l fmt) s, all isSpace r]
readSTime ::
ParseTime t
=> Bool
-> TimeLocale
-> String
-> ReadS t
readSTime acceptWS l f = readP_to_S $ readPTime acceptWS l f
readPSpecifiers ::
ParseTime t
=> Proxy t
-> Bool
-> TimeLocale
-> String
-> ReadP [(Char, String)]
readPSpecifiers pt False l f = parseSpecifiers pt l f
readPSpecifiers pt True l f = (skipSpaces >> parseSpecifiers pt l f) <++ parseSpecifiers pt l f
readPTime' ::
ParseTime t
=> Proxy t
-> Bool
-> TimeLocale
-> String
-> ReadP t
readPTime' pt ws l f = do
pairs <- readPSpecifiers pt ws l f
case buildTime l pairs of
Just t -> return t
Nothing -> pfail
readPTime ::
ParseTime t
=> Bool
-> TimeLocale
-> String
-> ReadP t
readPTime = readPTime' Proxy
instance Read Day where
readsPrec _ = readParen False $ readSTime True defaultTimeLocale "%Y-%m-%d"
instance Read TimeOfDay where
readsPrec _ = readParen False $ readSTime True defaultTimeLocale "%H:%M:%S%Q"
instance Read LocalTime where
readsPrec _ = readParen False $ readSTime True defaultTimeLocale "%Y-%m-%d %H:%M:%S%Q"
instance Read TimeZone where
readsPrec _ = readParen False $ readSTime True defaultTimeLocale "%Z"
instance Read ZonedTime where
readsPrec n = readParen False $ \s -> [(ZonedTime t z, r2) | (t, r1) <- readsPrec n s, (z, r2) <- readsPrec n r1]
instance Read UTCTime where
readsPrec n s = do
(lt, s') <- readsPrec n s
(tz, s'') <- readsPrec n s' <|> pure (utc, s')
return (localTimeToUTC tz lt, s'')
instance Read UniversalTime where
readsPrec n s = [(localTimeToUT1 0 t, r) | (t, r) <- readsPrec n s]