@@ -62,12 +62,12 @@ twoDigits = do
6262 let c2d c = ord c .&. 15
6363 return $! c2d a * 10 + c2d b
6464
65−-- | Parse a time of the form @HH:MM:SS[.SSS]@.
65+-- | Parse a time of the form @HH:MM[:SS[.SSS]]@.
6666timeOfDay :: Parser Local.TimeOfDay
6767timeOfDay = do
68− h <- twoDigits <* char ':'
69− m <- twoDigits <* char ':'
70− s <- seconds
68+ h <- twoDigits
69+ m <- char ':' *> twoDigits
70+ s <- option 0 (char ':' *> seconds)
7171 if h < 24 && m < 60 && s < 61
7272 then return (Local.TimeOfDay h m s)
7373 else fail "invalid time"
@@ -120,9 +120,9 @@ timeZone = do
120120 let !tz = Local.minutesToTimeZone off
121121 in return (Just tz)
122122
123−-- | Parse a date and time, of the form @YYYY-MM-DD HH:MM:SS@.
124−-- The space may be replaced with a @T@. The number of seconds may be
125−-- followed by a fractional component.
123+-- | Parse a date and time, of the form @YYYY-MM-DD HH:MM[:SS[.SSS]]@.
124+-- The space may be replaced with a @T@. The number of seconds is optional
125+-- and may be followed by a fractional component.
126126localTime :: Parser Local.LocalTime
127127localTime = Local.LocalTime <$> day <* daySep <*> timeOfDay
128128 where daySep = satisfy (\c -> c == 'T' || c == ' ')
@@ -140,7 +140,9 @@ utcTime = do
140140
141141-- | Parse a date with time zone info. Acceptable formats:
142142--
143+-- @YYYY-MM-DD HH:MM Z@
143144-- @YYYY-MM-DD HH:MM:SS Z@
145+-- @YYYY-MM-DD HH:MM:SS.SSS Z@
144146--
145147-- The first space may instead be a @T@, and the second space is
146148-- optional. The @Z@ represents UTC. The @Z@ may be replaced with a