parsing: more careful validation of eg leap years in transaction dates (only)

This commit is contained in:
Simon Michael 2011-04-22 13:55:42 +00:00
parent 6e100703b9
commit 1c7ad7f421
3 changed files with 15 additions and 18 deletions

View File

@ -18,6 +18,8 @@ quarterly, etc.
-} -}
-- XXX fromGregorian silently clips bad dates, use fromGregorianValid instead ?
module Hledger.Data.Dates module Hledger.Data.Dates
where where

View File

@ -347,20 +347,15 @@ ledgerdate = do
-- pos <- getPosition -- pos <- getPosition
datestr <- many1 $ choice' [digit, datesepchar] datestr <- many1 $ choice' [digit, datesepchar]
let dateparts = wordsBy (`elem` datesepchars) datestr let dateparts = wordsBy (`elem` datesepchars) datestr
case dateparts of currentyear <- getYear
[y,m,d] -> do let [y,m,d] = case (dateparts,currentyear) of
failIfInvalidYear y ([m,d],Just y) -> [show y,m,d]
failIfInvalidMonth m ([_,_],Nothing) -> fail $ "partial date "++datestr++" found, but the current year is unknown"
failIfInvalidDay d _ -> dateparts
return $ fromGregorian (read y) (read m) (read d) maybedate = fromGregorianValid (read y) (read m) (read d)
[m,d] -> do case maybedate of
y <- getYear Nothing -> fail $ "bad date: " ++ datestr
case y of Nothing -> fail "partial date found, but no default year specified" Just date -> return date
Just y' -> do failIfInvalidYear $ show y'
failIfInvalidMonth m
failIfInvalidDay d
return $ fromGregorian y' (read m) (read d)
_ -> fail $ "bad date: " ++ datestr
<?> "full or partial date" <?> "full or partial date"
ledgerdatetime :: GenParser Char JournalContext LocalTime ledgerdatetime :: GenParser Char JournalContext LocalTime

View File

@ -5,7 +5,7 @@ bin/hledger -f- print
2010/31/12 x 2010/31/12 x
a 1 a 1
b b
>>>2 /bad month number: 31/ >>>2 /bad date/
>>>= 1 >>>= 1
# 2. too-large day # 2. too-large day
bin/hledger -f- print bin/hledger -f- print
@ -13,7 +13,7 @@ bin/hledger -f- print
2010/12/32 x 2010/12/32 x
a 1 a 1
b b
>>>2 /bad day number: 32/ >>>2 /bad date/
>>>= 1 >>>= 1
# 3. 29th feb on leap year should be ok # 3. 29th feb on leap year should be ok
bin/hledger -f- print bin/hledger -f- print
@ -27,11 +27,11 @@ bin/hledger -f- print
b -1 b -1
>>>= 0 >>>= 0
# 3. 29th feb on non-leap year should fail # 4. 29th feb on non-leap year should fail
bin/hledger -f- print bin/hledger -f- print
<<< <<<
2001/2/29 x 2001/2/29 x
a 1 a 1
b b
>>>2 /bad day number: 29/ >>>2 /bad date/
>>>= 1 >>>= 1