From 8c3aa657b69ec28b4b9998a92d148b07896253d7 Mon Sep 17 00:00:00 2001 From: Max Bolingbroke Date: Tue, 21 Dec 2010 17:57:06 +0000 Subject: [PATCH] Add support for date-format conversion directive --- MANUAL.md | 7 ++++++- hledger/Hledger/Cli/Convert.hs | 20 ++++++++++++++++---- tests/convert.test | 9 +++++++++ 3 files changed, 31 insertions(+), 5 deletions(-) create mode 100644 tests/convert.test diff --git a/MANUAL.md b/MANUAL.md index fa26f38ee..5c840afa3 100644 --- a/MANUAL.md +++ b/MANUAL.md @@ -560,10 +560,15 @@ Notes: - Definitions must come first, one per line, all in one paragraph. Each is a name and a value separated by whitespace. - Supported names are: base-account, date-field, status-field, + Supported names are: base-account, date-field, date-format, status-field, code-field, description-field, amount-field, currency-field, currency. All are optional and will use defaults if not specified. +- The date-format field contains the expected format for the input dates: + this is the same as that accepted by the Haskell + [formatTime](http://hackage.haskell.org/packages/archive/time/latest/doc/html/Data-Time-Format.html#v:formatTime) + function. + - The remainder of the file is account-assigning rules. Each is a paragraph consisting of one or more description-matching patterns (case-insensitive regular expressions), one per line, followed by diff --git a/hledger/Hledger/Cli/Convert.hs b/hledger/Hledger/Cli/Convert.hs index c76193ad8..a466dc31a 100644 --- a/hledger/Hledger/Cli/Convert.hs +++ b/hledger/Hledger/Cli/Convert.hs @@ -35,6 +35,7 @@ convert a particular CSV data file into meaningful journal transactions. See abo -} data CsvRules = CsvRules { dateField :: Maybe FieldPosition, + dateFormat :: Maybe String, statusField :: Maybe FieldPosition, codeField :: Maybe FieldPosition, descriptionField :: Maybe FieldPosition, @@ -47,6 +48,7 @@ data CsvRules = CsvRules { nullrules = CsvRules { dateField=Nothing, + dateFormat=Nothing, statusField=Nothing, codeField=Nothing, descriptionField=Nothing, @@ -165,6 +167,7 @@ definitions :: GenParser Char CsvRules () definitions = do choice' [ datefield + ,dateformat ,statusfield ,codefield ,descriptionfield @@ -183,6 +186,13 @@ datefield = do r <- getState setState r{dateField=readMay v} +dateformat = do + string "date-format" + many1 spacenonewline + v <- restofline + r <- getState + setState r{dateFormat=Just v} + codefield = do string "code-field" many1 spacenonewline @@ -271,7 +281,7 @@ printTxn debug rules rec = do transactionFromCsvRecord :: CsvRules -> CsvRecord -> Transaction transactionFromCsvRecord rules fields = let - date = parsedate $ normaliseDate $ maybe "1900/1/1" (atDef "" fields) (dateField rules) + date = parsedate $ normaliseDate (dateFormat rules) $ maybe "1900/1/1" (atDef "" fields) (dateField rules) status = maybe False (null . strip . (atDef "" fields)) (statusField rules) code = maybe "" (atDef "" fields) (codeField rules) desc = maybe "" (atDef "" fields) (descriptionField rules) @@ -323,9 +333,11 @@ transactionFromCsvRecord rules fields = in t -- | Convert some date string with unknown format to YYYY/MM/DD. -normaliseDate :: String -> String -normaliseDate s = maybe "0000/00/00" showDate $ - firstJust +normaliseDate :: Maybe String -- ^ User-supplied date format: this should be tried in preference to all others + -> String -> String +normaliseDate mb_user_format s = maybe "0000/00/00" showDate $ + firstJust $ + (maybe id (\user_format -> (parseTime defaultTimeLocale user_format s :)) mb_user_format) $ [parseTime defaultTimeLocale "%Y/%m/%e" s -- can't parse a month without leading 0, try adding one ,parseTime defaultTimeLocale "%Y/%m/%e" (take 5 s ++ "0" ++ drop 5 s) diff --git a/tests/convert.test b/tests/convert.test new file mode 100644 index 000000000..3318ff22f --- /dev/null +++ b/tests/convert.test @@ -0,0 +1,9 @@ +# Conversion from CSV to Ledger +printf 'base-account Assets:MyAccount\ndate-field 0\ndate-format %%d/%%Y/%%m\ndescription-field 1\namount-field 2\ncurrency $\n' >input.rules ; printf '10/2009/09,Flubber Co,50' > input.csv ; touch unused.journal ; bin/hledger -f unused.journal convert input.csv ; rm -rf unused.journal input.rules input.csv +>>> +2009/09/10 Flubber Co + income:unknown $-50 + Assets:MyAccount $50 + +>>>2 +using conversion rules file input.rules