{-# OPTIONS -fno-warn-orphans #-}
module Data.Time.Format.Parse
    (
    
    parseTimeM, parseTimeOrError, readSTime, readPTime,
    parseTime, readTime, readsTime,
    ParseTime(),
    
    module Data.Time.Format.Locale
    ) where
import Data.Proxy
#if MIN_VERSION_base(4,9,0)
import Control.Monad.Fail
import Prelude hiding (fail)
#endif
import Data.Char
import Data.Time.Format.Locale
import Text.ParserCombinators.ReadP hiding (char, string)
import Data.Time.Clock.Internal.UniversalTime
import Data.Time.Clock.Internal.UTCTime
import Data.Time.Calendar.Days
import Data.Time.LocalTime.Internal.TimeZone
import Data.Time.LocalTime.Internal.TimeOfDay
import Data.Time.LocalTime.Internal.LocalTime
import Data.Time.LocalTime.Internal.ZonedTime
import Data.Time.Format.Parse.Class
import Data.Time.Format.Parse.Instances()
parseTimeM :: (
#if MIN_VERSION_base(4,9,0)
    MonadFail m
#else
    Monad m
#endif
    ,ParseTime t) =>
             Bool       
          -> TimeLocale 
          -> String     
          -> String     
          -> m t    
                        
parseTimeM acceptWS l fmt s = case parseTimeList acceptWS l fmt s of
    [t] -> return t
    []  -> fail $ "parseTimeM: no parse of " ++ show s
    _   -> fail $ "parseTimeM: multiple parses of " ++ show s
parseTimeOrError :: ParseTime t =>
             Bool       
          -> TimeLocale 
          -> String     
          -> String     
          -> t          
parseTimeOrError acceptWS l fmt s = case parseTimeList acceptWS l fmt s of
    [t] -> t
    []  -> error $ "parseTimeOrError: no parse of " ++ show s
    _   -> error $ "parseTimeOrError: multiple parses of " ++ show s
parseTimeList :: ParseTime t =>
             Bool       
          -> TimeLocale 
          -> String     
          -> String     
          -> [t]
parseTimeList False l fmt s = [t | (t,"") <- readSTime False l fmt s]
parseTimeList True l fmt s = [t | (t,r) <- readSTime 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)
readPTime :: ParseTime t =>
             Bool       
          -> TimeLocale 
          -> String     
          -> ReadP t
readPTime False l f = readPOnlyTime l f
readPTime True l f = (skipSpaces >> readPOnlyTime l f) <++ readPOnlyTime l f
readPOnlyTime' :: ParseTime t => proxy t -> TimeLocale -> String -> ReadP t
readPOnlyTime' pt l f = do
    pairs <- parseSpecifiers pt l f
    case buildTime l pairs of
        Just t -> return t
        Nothing -> pfail
readPOnlyTime :: ParseTime t =>
             TimeLocale 
          -> String     
          -> ReadP t
readPOnlyTime = readPOnlyTime' Proxy
{-# DEPRECATED parseTime "use \"parseTimeM True\" instead" #-}
parseTime :: ParseTime t =>
             TimeLocale 
          -> String     
          -> String     
          -> Maybe t    
                        
parseTime = parseTimeM True
{-# DEPRECATED readTime "use \"parseTimeOrError True\" instead" #-}
readTime :: ParseTime t =>
            TimeLocale 
         -> String     
         -> String     
         -> t          
readTime = parseTimeOrError True
{-# DEPRECATED readsTime "use \"readSTime True\" instead" #-}
readsTime :: ParseTime t =>
             TimeLocale 
          -> String     
          -> ReadS t
readsTime = readSTime True
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 = [ (zonedTimeToUTC t, r) | (t,r) <- readsPrec n s ]
instance Read UniversalTime where
    readsPrec n s = [ (localTimeToUT1 0 t, r) | (t,r) <- readsPrec n s ]