{-# LANGUAGE Safe #-}
module Data.Time.Format.Parse.Class (
ParseNumericPadding (..),
ParseTime (..),
parseSpecifiers,
timeSubstituteTimeSpecifier,
timeParseTimeSpecifier,
durationParseTimeSpecifier,
) where
import Data.Char
import Data.Maybe
import Data.Proxy
import Data.Time.Format.Locale
import Text.ParserCombinators.ReadP
data ParseNumericPadding
= NoPadding
| SpacePadding
| ZeroPadding
class ParseTime t where
substituteTimeSpecifier :: Proxy t -> TimeLocale -> Char -> Maybe String
substituteTimeSpecifier Proxy t
_ TimeLocale
_ Char
_ = Maybe String
forall a. Maybe a
Nothing
parseTimeSpecifier :: Proxy t -> TimeLocale -> Maybe ParseNumericPadding -> Char -> ReadP String
buildTime ::
TimeLocale ->
[(Char, String)] ->
Maybe t
charCI :: Char -> ReadP Char
charCI :: Char -> ReadP Char
charCI Char
c = (Char -> Bool) -> ReadP Char
satisfy (\Char
x -> Char -> Char
toUpper Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char -> Char
toUpper Char
x)
stringCI :: String -> ReadP String
stringCI :: String -> ReadP String
stringCI String
this = do
let
scan :: String -> String -> ReadP String
scan [] String
_ = String -> ReadP String
forall a. a -> ReadP a
forall (m :: * -> *) a. Monad m => a -> m a
return String
this
scan (Char
x : String
xs) (Char
y : String
ys)
| Char -> Char
toUpper Char
x Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char -> Char
toUpper Char
y = do
_ <- ReadP Char
get
scan xs ys
scan String
_ String
_ = ReadP String
forall a. ReadP a
pfail
s <- ReadP String
look
scan this s
parseSpecifiers :: ParseTime t => Proxy t -> TimeLocale -> String -> ReadP [(Char, String)]
parseSpecifiers :: forall t.
ParseTime t =>
Proxy t -> TimeLocale -> String -> ReadP [(Char, String)]
parseSpecifiers Proxy t
pt TimeLocale
locale = let
parse :: String -> ReadP [(Char, String)]
parse :: String -> ReadP [(Char, String)]
parse [] = [(Char, String)] -> ReadP [(Char, String)]
forall a. a -> ReadP a
forall (m :: * -> *) a. Monad m => a -> m a
return []
parse (Char
'%' : String
cs) = String -> ReadP [(Char, String)]
parse1 String
cs
parse (Char
c : String
cs) | Char -> Bool
isSpace Char
c = do
_ <- (Char -> Bool) -> ReadP Char
satisfy Char -> Bool
isSpace
case cs of
(Char
c' : String
_) | Char -> Bool
isSpace Char
c' -> () -> ReadP ()
forall a. a -> ReadP a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
String
_ -> ReadP ()
skipSpaces
parse cs
parse (Char
c : String
cs) = do
_ <- Char -> ReadP Char
charCI Char
c
parse cs
parse1 :: String -> ReadP [(Char, String)]
parse1 :: String -> ReadP [(Char, String)]
parse1 (Char
'-' : String
cs) = Maybe ParseNumericPadding -> String -> ReadP [(Char, String)]
parse2 (ParseNumericPadding -> Maybe ParseNumericPadding
forall a. a -> Maybe a
Just ParseNumericPadding
NoPadding) String
cs
parse1 (Char
'_' : String
cs) = Maybe ParseNumericPadding -> String -> ReadP [(Char, String)]
parse2 (ParseNumericPadding -> Maybe ParseNumericPadding
forall a. a -> Maybe a
Just ParseNumericPadding
SpacePadding) String
cs
parse1 (Char
'0' : String
cs) = Maybe ParseNumericPadding -> String -> ReadP [(Char, String)]
parse2 (ParseNumericPadding -> Maybe ParseNumericPadding
forall a. a -> Maybe a
Just ParseNumericPadding
ZeroPadding) String
cs
parse1 String
cs = Maybe ParseNumericPadding -> String -> ReadP [(Char, String)]
parse2 Maybe ParseNumericPadding
forall a. Maybe a
Nothing String
cs
parse2 :: Maybe ParseNumericPadding -> String -> ReadP [(Char, String)]
parse2 :: Maybe ParseNumericPadding -> String -> ReadP [(Char, String)]
parse2 Maybe ParseNumericPadding
mpad (Char
'E' : String
cs) = Maybe ParseNumericPadding
-> Bool -> String -> ReadP [(Char, String)]
parse3 Maybe ParseNumericPadding
mpad Bool
True String
cs
parse2 Maybe ParseNumericPadding
mpad String
cs = Maybe ParseNumericPadding
-> Bool -> String -> ReadP [(Char, String)]
parse3 Maybe ParseNumericPadding
mpad Bool
False String
cs
parse3 :: Maybe ParseNumericPadding -> Bool -> String -> ReadP [(Char, String)]
parse3 :: Maybe ParseNumericPadding
-> Bool -> String -> ReadP [(Char, String)]
parse3 Maybe ParseNumericPadding
_ Bool
_ (Char
'%' : String
cs) = do
_ <- Char -> ReadP Char
char Char
'%'
parse cs
parse3 Maybe ParseNumericPadding
_ Bool
_ (Char
c : String
cs) | Just String
s <- Proxy t -> TimeLocale -> Char -> Maybe String
forall t.
ParseTime t =>
Proxy t -> TimeLocale -> Char -> Maybe String
substituteTimeSpecifier Proxy t
pt TimeLocale
locale Char
c = String -> ReadP [(Char, String)]
parse (String -> ReadP [(Char, String)])
-> String -> ReadP [(Char, String)]
forall a b. (a -> b) -> a -> b
$ String
s String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
cs
parse3 Maybe ParseNumericPadding
mpad Bool
_alt (Char
c : String
cs) = do
str <- Proxy t
-> TimeLocale -> Maybe ParseNumericPadding -> Char -> ReadP String
forall t.
ParseTime t =>
Proxy t
-> TimeLocale -> Maybe ParseNumericPadding -> Char -> ReadP String
parseTimeSpecifier Proxy t
pt TimeLocale
locale Maybe ParseNumericPadding
mpad Char
c
specs <- parse cs
return $ (c, str) : specs
parse3 Maybe ParseNumericPadding
_ Bool
_ [] = [(Char, String)] -> ReadP [(Char, String)]
forall a. a -> ReadP a
forall (m :: * -> *) a. Monad m => a -> m a
return []
in String -> ReadP [(Char, String)]
parse
data PaddingSide
= PrePadding
| PostPadding
allowEmptyParser :: Bool -> ReadP String
allowEmptyParser :: Bool -> ReadP String
allowEmptyParser Bool
False = ReadP Char -> ReadP String
forall a. ReadP a -> ReadP [a]
many1 ((Char -> Bool) -> ReadP Char
satisfy Char -> Bool
isDigit)
allowEmptyParser Bool
True = ReadP Char -> ReadP String
forall a. ReadP a -> ReadP [a]
many ((Char -> Bool) -> ReadP Char
satisfy Char -> Bool
isDigit)
parsePaddedDigits :: PaddingSide -> ParseNumericPadding -> Bool -> Int -> ReadP String
parsePaddedDigits :: PaddingSide -> ParseNumericPadding -> Bool -> Int -> ReadP String
parsePaddedDigits PaddingSide
_ ParseNumericPadding
ZeroPadding Bool
_ Int
n = Int -> ReadP Char -> ReadP String
forall a. Int -> ReadP a -> ReadP [a]
count Int
n ((Char -> Bool) -> ReadP Char
satisfy Char -> Bool
isDigit)
parsePaddedDigits PaddingSide
PrePadding ParseNumericPadding
SpacePadding Bool
allowEmpty Int
_n = ReadP ()
skipSpaces ReadP () -> ReadP String -> ReadP String
forall a b. ReadP a -> ReadP b -> ReadP b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Bool -> ReadP String
allowEmptyParser Bool
allowEmpty
parsePaddedDigits PaddingSide
PostPadding ParseNumericPadding
SpacePadding Bool
allowEmpty Int
_n = do
r <- Bool -> ReadP String
allowEmptyParser Bool
allowEmpty
skipSpaces
return r
parsePaddedDigits PaddingSide
_ ParseNumericPadding
NoPadding Bool
False Int
_n = ReadP Char -> ReadP String
forall a. ReadP a -> ReadP [a]
many1 ((Char -> Bool) -> ReadP Char
satisfy Char -> Bool
isDigit)
parsePaddedDigits PaddingSide
_ ParseNumericPadding
NoPadding Bool
True Int
_n = ReadP Char -> ReadP String
forall a. ReadP a -> ReadP [a]
many ((Char -> Bool) -> ReadP Char
satisfy Char -> Bool
isDigit)
parsePaddedSignedDigits :: ParseNumericPadding -> Int -> ReadP String
parsePaddedSignedDigits :: ParseNumericPadding -> Int -> ReadP String
parsePaddedSignedDigits ParseNumericPadding
pad Int
n = do
sign <- String -> ReadP String -> ReadP String
forall a. a -> ReadP a -> ReadP a
option String
"" (ReadP String -> ReadP String) -> ReadP String -> ReadP String
forall a b. (a -> b) -> a -> b
$ Char -> ReadP Char
char Char
'-' ReadP Char -> ReadP String -> ReadP String
forall a b. ReadP a -> ReadP b -> ReadP b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> String -> ReadP String
forall a. a -> ReadP a
forall (m :: * -> *) a. Monad m => a -> m a
return String
"-"
digits <- parsePaddedDigits PrePadding pad False n
return $ sign ++ digits
parseSignedDecimal :: ReadP String
parseSignedDecimal :: ReadP String
parseSignedDecimal = do
sign <- String -> ReadP String -> ReadP String
forall a. a -> ReadP a -> ReadP a
option String
"" (ReadP String -> ReadP String) -> ReadP String -> ReadP String
forall a b. (a -> b) -> a -> b
$ Char -> ReadP Char
char Char
'-' ReadP Char -> ReadP String -> ReadP String
forall a b. ReadP a -> ReadP b -> ReadP b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> String -> ReadP String
forall a. a -> ReadP a
forall (m :: * -> *) a. Monad m => a -> m a
return String
"-"
skipSpaces
digits <- many1 $ satisfy isDigit
decimaldigits <-
option "" $ do
_ <- char '.'
dd <- many $ satisfy isDigit
return $ '.' : dd
return $ sign ++ digits ++ decimaldigits
timeParseTimeSpecifier :: TimeLocale -> Maybe ParseNumericPadding -> Char -> ReadP String
timeParseTimeSpecifier :: TimeLocale -> Maybe ParseNumericPadding -> Char -> ReadP String
timeParseTimeSpecifier TimeLocale
l Maybe ParseNumericPadding
mpad Char
c = let
digits' :: PaddingSide -> ParseNumericPadding -> Bool -> Int -> ReadP String
digits' PaddingSide
ps ParseNumericPadding
pad = PaddingSide -> ParseNumericPadding -> Bool -> Int -> ReadP String
parsePaddedDigits PaddingSide
ps (ParseNumericPadding
-> Maybe ParseNumericPadding -> ParseNumericPadding
forall a. a -> Maybe a -> a
fromMaybe ParseNumericPadding
pad Maybe ParseNumericPadding
mpad)
digits :: ParseNumericPadding -> Int -> ReadP String
digits ParseNumericPadding
pad = PaddingSide -> ParseNumericPadding -> Bool -> Int -> ReadP String
digits' PaddingSide
PrePadding ParseNumericPadding
pad Bool
False
oneOf :: [String] -> ReadP String
oneOf = [ReadP String] -> ReadP String
forall a. [ReadP a] -> ReadP a
choice ([ReadP String] -> ReadP String)
-> ([String] -> [ReadP String]) -> [String] -> ReadP String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (String -> ReadP String) -> [String] -> [ReadP String]
forall a b. (a -> b) -> [a] -> [b]
map String -> ReadP String
stringCI
numericTZ :: ReadP String
numericTZ = do
s <- [ReadP Char] -> ReadP Char
forall a. [ReadP a] -> ReadP a
choice [Char -> ReadP Char
char Char
'+', Char -> ReadP Char
char Char
'-']
h <- parsePaddedDigits PrePadding ZeroPadding False 2
optional (char ':')
m <- parsePaddedDigits PrePadding ZeroPadding False 2
return (s : h ++ m)
allowNegative :: ReadP String -> ReadP String
allowNegative :: ReadP String -> ReadP String
allowNegative ReadP String
p = (Char -> ReadP Char
char Char
'-' ReadP Char -> ReadP String -> ReadP String
forall a b. ReadP a -> ReadP b -> ReadP b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> (String -> String) -> ReadP String -> ReadP String
forall a b. (a -> b) -> ReadP a -> ReadP b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Char
'-' Char -> String -> String
forall a. a -> [a] -> [a]
:) ReadP String
p) ReadP String -> ReadP String -> ReadP String
forall a. ReadP a -> ReadP a -> ReadP a
<++ ReadP String
p
in case Char
c of
Char
'C' -> ReadP String -> ReadP String
allowNegative (ReadP String -> ReadP String) -> ReadP String -> ReadP String
forall a b. (a -> b) -> a -> b
$ ParseNumericPadding -> Int -> ReadP String
digits ParseNumericPadding
SpacePadding Int
2
Char
'f' -> ReadP String -> ReadP String
allowNegative (ReadP String -> ReadP String) -> ReadP String -> ReadP String
forall a b. (a -> b) -> a -> b
$ ParseNumericPadding -> Int -> ReadP String
digits ParseNumericPadding
SpacePadding Int
2
Char
'Y' -> ReadP String -> ReadP String
allowNegative (ReadP String -> ReadP String) -> ReadP String -> ReadP String
forall a b. (a -> b) -> a -> b
$ ParseNumericPadding -> Int -> ReadP String
digits ParseNumericPadding
SpacePadding Int
4
Char
'G' -> ReadP String -> ReadP String
allowNegative (ReadP String -> ReadP String) -> ReadP String -> ReadP String
forall a b. (a -> b) -> a -> b
$ ParseNumericPadding -> Int -> ReadP String
digits ParseNumericPadding
SpacePadding Int
4
Char
'y' -> ParseNumericPadding -> Int -> ReadP String
digits ParseNumericPadding
ZeroPadding Int
2
Char
'g' -> ParseNumericPadding -> Int -> ReadP String
digits ParseNumericPadding
ZeroPadding Int
2
Char
'B' -> [String] -> ReadP String
oneOf (((String, String) -> String) -> [(String, String)] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map (String, String) -> String
forall a b. (a, b) -> a
fst (TimeLocale -> [(String, String)]
months TimeLocale
l))
Char
'b' -> [String] -> ReadP String
oneOf (((String, String) -> String) -> [(String, String)] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map (String, String) -> String
forall a b. (a, b) -> b
snd (TimeLocale -> [(String, String)]
months TimeLocale
l))
Char
'm' -> ParseNumericPadding -> Int -> ReadP String
digits ParseNumericPadding
ZeroPadding Int
2
Char
'd' -> ParseNumericPadding -> Int -> ReadP String
digits ParseNumericPadding
ZeroPadding Int
2
Char
'e' -> ParseNumericPadding -> Int -> ReadP String
digits ParseNumericPadding
SpacePadding Int
2
Char
'V' -> ParseNumericPadding -> Int -> ReadP String
digits ParseNumericPadding
ZeroPadding Int
2
Char
'U' -> ParseNumericPadding -> Int -> ReadP String
digits ParseNumericPadding
ZeroPadding Int
2
Char
'W' -> ParseNumericPadding -> Int -> ReadP String
digits ParseNumericPadding
ZeroPadding Int
2
Char
'u' -> [String] -> ReadP String
oneOf ([String] -> ReadP String) -> [String] -> ReadP String
forall a b. (a -> b) -> a -> b
$ (Char -> String) -> String -> [String]
forall a b. (a -> b) -> [a] -> [b]
map (Char -> String -> String
forall a. a -> [a] -> [a]
: []) [Char
'1' .. Char
'7']
Char
'a' -> [String] -> ReadP String
oneOf (((String, String) -> String) -> [(String, String)] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map (String, String) -> String
forall a b. (a, b) -> b
snd (TimeLocale -> [(String, String)]
wDays TimeLocale
l))
Char
'A' -> [String] -> ReadP String
oneOf (((String, String) -> String) -> [(String, String)] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map (String, String) -> String
forall a b. (a, b) -> a
fst (TimeLocale -> [(String, String)]
wDays TimeLocale
l))
Char
'w' -> [String] -> ReadP String
oneOf ([String] -> ReadP String) -> [String] -> ReadP String
forall a b. (a -> b) -> a -> b
$ (Char -> String) -> String -> [String]
forall a b. (a -> b) -> [a] -> [b]
map (Char -> String -> String
forall a. a -> [a] -> [a]
: []) [Char
'0' .. Char
'6']
Char
'j' -> ParseNumericPadding -> Int -> ReadP String
digits ParseNumericPadding
ZeroPadding Int
3
Char
'P' ->
[String] -> ReadP String
oneOf
( let
(String
am, String
pm) = TimeLocale -> (String, String)
amPm TimeLocale
l
in [String
am, String
pm]
)
Char
'p' ->
[String] -> ReadP String
oneOf
( let
(String
am, String
pm) = TimeLocale -> (String, String)
amPm TimeLocale
l
in [String
am, String
pm]
)
Char
'H' -> ParseNumericPadding -> Int -> ReadP String
digits ParseNumericPadding
ZeroPadding Int
2
Char
'k' -> ParseNumericPadding -> Int -> ReadP String
digits ParseNumericPadding
SpacePadding Int
2
Char
'I' -> ParseNumericPadding -> Int -> ReadP String
digits ParseNumericPadding
ZeroPadding Int
2
Char
'l' -> ParseNumericPadding -> Int -> ReadP String
digits ParseNumericPadding
SpacePadding Int
2
Char
'M' -> ParseNumericPadding -> Int -> ReadP String
digits ParseNumericPadding
ZeroPadding Int
2
Char
'S' -> ParseNumericPadding -> Int -> ReadP String
digits ParseNumericPadding
ZeroPadding Int
2
Char
'q' -> PaddingSide -> ParseNumericPadding -> Bool -> Int -> ReadP String
digits' PaddingSide
PostPadding ParseNumericPadding
ZeroPadding Bool
True Int
12
Char
'Q' -> (Char -> ReadP Char
char Char
'.' ReadP Char -> ReadP String -> ReadP String
forall a b. ReadP a -> ReadP b -> ReadP b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> PaddingSide -> ParseNumericPadding -> Bool -> Int -> ReadP String
digits' PaddingSide
PostPadding ParseNumericPadding
NoPadding Bool
True Int
12) ReadP String -> ReadP String -> ReadP String
forall a. ReadP a -> ReadP a -> ReadP a
<++ String -> ReadP String
forall a. a -> ReadP a
forall (m :: * -> *) a. Monad m => a -> m a
return String
""
Char
'z' -> ReadP String
numericTZ
Char
'Z' -> (Char -> Bool) -> ReadP String
munch1 Char -> Bool
isAlpha ReadP String -> ReadP String -> ReadP String
forall a. ReadP a -> ReadP a -> ReadP a
<++ ReadP String
numericTZ
Char
's' -> (Char -> ReadP Char
char Char
'-' ReadP Char -> ReadP String -> ReadP String
forall a b. ReadP a -> ReadP b -> ReadP b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> (String -> String) -> ReadP String -> ReadP String
forall a b. (a -> b) -> ReadP a -> ReadP b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Char
'-' Char -> String -> String
forall a. a -> [a] -> [a]
:) ((Char -> Bool) -> ReadP String
munch1 Char -> Bool
isDigit)) ReadP String -> ReadP String -> ReadP String
forall a. ReadP a -> ReadP a -> ReadP a
<++ (Char -> Bool) -> ReadP String
munch1 Char -> Bool
isDigit
Char
_ -> String -> ReadP String
forall a. String -> ReadP a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> ReadP String) -> String -> ReadP String
forall a b. (a -> b) -> a -> b
$ String
"Unknown format character: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Char -> String
forall a. Show a => a -> String
show Char
c
timeSubstituteTimeSpecifier :: TimeLocale -> Char -> Maybe String
timeSubstituteTimeSpecifier :: TimeLocale -> Char -> Maybe String
timeSubstituteTimeSpecifier TimeLocale
l Char
'c' = String -> Maybe String
forall a. a -> Maybe a
Just (String -> Maybe String) -> String -> Maybe String
forall a b. (a -> b) -> a -> b
$ TimeLocale -> String
dateTimeFmt TimeLocale
l
timeSubstituteTimeSpecifier TimeLocale
_ Char
'R' = String -> Maybe String
forall a. a -> Maybe a
Just String
"%H:%M"
timeSubstituteTimeSpecifier TimeLocale
_ Char
'T' = String -> Maybe String
forall a. a -> Maybe a
Just String
"%H:%M:%S"
timeSubstituteTimeSpecifier TimeLocale
l Char
'X' = String -> Maybe String
forall a. a -> Maybe a
Just (String -> Maybe String) -> String -> Maybe String
forall a b. (a -> b) -> a -> b
$ TimeLocale -> String
timeFmt TimeLocale
l
timeSubstituteTimeSpecifier TimeLocale
l Char
'r' = String -> Maybe String
forall a. a -> Maybe a
Just (String -> Maybe String) -> String -> Maybe String
forall a b. (a -> b) -> a -> b
$ TimeLocale -> String
time12Fmt TimeLocale
l
timeSubstituteTimeSpecifier TimeLocale
_ Char
'D' = String -> Maybe String
forall a. a -> Maybe a
Just String
"%m/%d/%y"
timeSubstituteTimeSpecifier TimeLocale
_ Char
'F' = String -> Maybe String
forall a. a -> Maybe a
Just String
"%Y-%m-%d"
timeSubstituteTimeSpecifier TimeLocale
l Char
'x' = String -> Maybe String
forall a. a -> Maybe a
Just (String -> Maybe String) -> String -> Maybe String
forall a b. (a -> b) -> a -> b
$ TimeLocale -> String
dateFmt TimeLocale
l
timeSubstituteTimeSpecifier TimeLocale
_ Char
'h' = String -> Maybe String
forall a. a -> Maybe a
Just String
"%b"
timeSubstituteTimeSpecifier TimeLocale
_ Char
_ = Maybe String
forall a. Maybe a
Nothing
durationParseTimeSpecifier :: TimeLocale -> Maybe ParseNumericPadding -> Char -> ReadP String
durationParseTimeSpecifier :: TimeLocale -> Maybe ParseNumericPadding -> Char -> ReadP String
durationParseTimeSpecifier TimeLocale
_ Maybe ParseNumericPadding
mpad Char
c = let
padopt :: Int -> ReadP String
padopt = ParseNumericPadding -> Int -> ReadP String
parsePaddedSignedDigits (ParseNumericPadding -> Int -> ReadP String)
-> ParseNumericPadding -> Int -> ReadP String
forall a b. (a -> b) -> a -> b
$ ParseNumericPadding
-> Maybe ParseNumericPadding -> ParseNumericPadding
forall a. a -> Maybe a -> a
fromMaybe ParseNumericPadding
NoPadding Maybe ParseNumericPadding
mpad
in case Char
c of
Char
'y' -> Int -> ReadP String
padopt Int
1
Char
'b' -> Int -> ReadP String
padopt Int
1
Char
'B' -> Int -> ReadP String
padopt Int
2
Char
'w' -> Int -> ReadP String
padopt Int
1
Char
'd' -> Int -> ReadP String
padopt Int
1
Char
'D' -> Int -> ReadP String
padopt Int
1
Char
'h' -> Int -> ReadP String
padopt Int
1
Char
'H' -> Int -> ReadP String
padopt Int
2
Char
'm' -> Int -> ReadP String
padopt Int
1
Char
'M' -> Int -> ReadP String
padopt Int
2
Char
's' -> ReadP String
parseSignedDecimal
Char
'S' -> ReadP String
parseSignedDecimal
Char
_ -> String -> ReadP String
forall a. String -> ReadP a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> ReadP String) -> String -> ReadP String
forall a b. (a -> b) -> a -> b
$ String
"Unknown format character: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Char -> String
forall a. Show a => a -> String
show Char
c