parser :: Stream s m Char => ParsecT s u m ZonedTime
parser = dateTime
-
dateTime :: Stream s m Char => ParsecT s u m ZonedTime
dateTime = do weekDay <- optionMaybe $
do w <- shortWeekDayNameP
Nothing
-> return () -- No day in week exists.
Just givenWD
- -> let (_, _, correctWD) = toWeekDate gregDay
- in
- if correctWD == givenWD then
- return () -- Correct day in the week.
- else
- let (year, month, day) = toGregorian gregDay
- in
- fail $ concat [ "Gregorian day "
- , show year
- , "-"
- , show month
- , "-"
- , show day
- , " is "
- , longWeekDayName correctWD
- , ", not "
- , longWeekDayName givenWD
- ]
+ -> assertWeekDayIsGood givenWD gregDay
(tod, timeZone) <- time
- return ZonedTime {
- zonedTimeToLocalTime = LocalTime {
- localDay = gregDay
- , localTimeOfDay = tod
- }
- , zonedTimeZone = timeZone
- }
+ let lt = LocalTime gregDay tod
+ zt = ZonedTime lt timeZone
+ return zt
date :: Stream s m Char => ParsecT s u m Day
date = do day <- read2
_ <- char ' '
year <- liftM (+ 1900) read2
_ <- char ' '
-
- case fromGregorianValid (toInteger year) month day of
- Nothing
- -> fail $ concat [ "Invalid gregorian day: "
- , show year
- , "-"
- , show month
- , "-"
- , show day
- ]
- Just gregDay
- -> return gregDay
+ assertGregorianDateIsGood (toInteger year) month day
time :: Stream s m Char => ParsecT s u m (TimeOfDay, TimeZone)
time = do tod <- hour
hour = do hour <- read2
minute <- char ':' >> read2
second <- option 0 (char ':' >> read2)
- case makeTimeOfDayValid hour minute second of
- Nothing
- -> fail $ concat [ "Invalid time of day: "
- , show hour
- , ":"
- , show minute
- , ":"
- , showFixed True second
- ]
- Just tod
- -> return tod
+ assertTimeOfDayIsGood hour minute second
zone :: Stream s m Char => ParsecT s u m TimeZone
zone = choice [ string "UT" >> return (TimeZone 0 False "UT" )
, char 'A' >> return (TimeZone ((-1) * 60) False "A")
, char 'N' >> return (TimeZone ( 1 * 60) False "N")
, char 'Y' >> return (TimeZone ( 12 * 60) False "Y")
- , do sign <- (char '+' >> return 1)
- <|>
- (char '-' >> return (-1))
- hour <- read2
- minute <- read2
- let tz = TimeZone {
- timeZoneMinutes = (sign * (hour * 60 + minute))
- , timeZoneSummerOnly = False
- , timeZoneName = timeZoneOffsetString tz
- }
- return tz
+ , read4digitsTZ
]