timelog: support the description field (fix #247)

This commit is contained in:
Simon Michael 2015-04-28 13:54:36 -07:00
parent fb37e99bc8
commit 5102eca9c3
6 changed files with 62 additions and 28 deletions

View File

@ -738,21 +738,39 @@ The original order of same-day entries will be preserved, usually.
### Timelog
hledger can also read time log files. These are (a subset of) timeclock.el's
format, containing clock-in and clock-out entries like so:
hledger can also read timelog files.
[As with Ledger](http://ledger-cli.org/3.0/doc/ledger3.html#Time-Keeping),
these are (a subset of)
[timeclock.el](http://www.emacswiki.org/emacs/TimeClock)'s format,
containing clock-in and clock-out entries like so:
i 2009/03/31 22:21:45 projects:A
o 2009/04/01 02:00:34
i 2015/03/30 09:00:00 some:account name optional description after two spaces
o 2015/03/30 09:20:00
i 2015/03/31 22:21:45 another account
o 2015/04/01 02:00:34
hledger treats the clock-in description ("projects:A") as an account name,
and creates a virtual transaction (or several - one per day) with the
appropriate amount of hours. From the time log above, hledger print gives:
The date is a [simple date](#simple-dates), so hyphen (-) and period
(.) are also allowed as separators, leading zeroes are optional, the
year may be omitted (and a [default year directive](#default-year) can
be used to set it).
2009/03/31 * 22:21-23:59
(projects:A) 1.64h
2009/04/01 * 00:00-02:00
(projects:A) 2.01h
The time format is HH:MM[:SS][+-ZZZZ]. Seconds and timezone are optional.
The timezone, if present, must be four digits and is ignored
(currently the time is always interpreted as a local time).
hledger treats each clock-in/clock-out pair as a transaction posting
some number of hours to a (single) account. Or, several transactions
if the session spans more than one day. Eg for the above time log,
hledger print gives:
2015/03/30 * optional description after two spaces
(some:account name) 0.33h
2015/03/31 * 22:21-23:59
(another account) 1.64h
2015/04/01 * 00:00-02:00
(another account) 2.01h
Here is a
[sample.timelog](https://raw.github.com/simonmichael/hledger/master/data/sample.timelog) to

View File

@ -28,7 +28,7 @@ import Hledger.Data.Posting
import Hledger.Data.Transaction
instance Show TimeLogEntry where
show t = printf "%s %s %s" (show $ tlcode t) (show $ tldatetime t) (tlcomment t)
show t = printf "%s %s %s %s" (show $ tlcode t) (show $ tldatetime t) (tlaccount t) (tldescription t)
instance Show TimeLogCode where
show SetBalance = "b"
@ -54,7 +54,7 @@ timeLogEntriesToTransactions now [i]
| odate > idate = entryFromTimeLogInOut i o' : timeLogEntriesToTransactions now [i',o]
| otherwise = [entryFromTimeLogInOut i o]
where
o = TimeLogEntry (tlsourcepos i) Out end ""
o = TimeLogEntry (tlsourcepos i) Out end "" ""
end = if itime > now then itime else now
(itime,otime) = (tldatetime i,tldatetime o)
(idate,odate) = (localDay itime,localDay otime)
@ -84,20 +84,22 @@ entryFromTimeLogInOut i o
tdate2 = Nothing,
tstatus = True,
tcode = "",
tdescription = showtime itod ++ "-" ++ showtime otod,
tdescription = desc,
tcomment = "",
ttags = [],
tpostings = ps,
tpreceding_comment_lines=""
}
showtime = take 5 . show
acctname = tlcomment i
itime = tldatetime i
otime = tldatetime o
itod = localTimeOfDay itime
otod = localTimeOfDay otime
idate = localDay itime
desc | null (tldescription i) = showtime itod ++ "-" ++ showtime otod
| otherwise = tldescription i
showtime = take 5 . show
hours = elapsedSeconds (toutc otime) (toutc itime) / 3600 where toutc = localTimeToUTC utc
acctname = tlaccount i
amount = Mixed [hrs hours]
ps = [posting{paccount=acctname, pamount=amount, ptype=VirtualPosting, ptransaction=Just t}]
@ -122,18 +124,18 @@ tests_Hledger_Data_TimeLog = TestList [
assertEntriesGiveStrings name es ss = assertEqual name ss (map tdescription $ timeLogEntriesToTransactions now es)
assertEntriesGiveStrings "started yesterday, split session at midnight"
[clockin (mktime yesterday "23:00:00") ""]
[clockin (mktime yesterday "23:00:00") "" ""]
["23:00-23:59","00:00-"++nowstr]
assertEntriesGiveStrings "split multi-day sessions at each midnight"
[clockin (mktime (addDays (-2) today) "23:00:00") ""]
[clockin (mktime (addDays (-2) today) "23:00:00") "" ""]
["23:00-23:59","00:00-23:59","00:00-"++nowstr]
assertEntriesGiveStrings "auto-clock-out if needed"
[clockin (mktime today "00:00:00") ""]
[clockin (mktime today "00:00:00") "" ""]
["00:00-"++nowstr]
let future = utcToLocalTime tz $ addUTCTime 100 now'
futurestr = showtime future
assertEntriesGiveStrings "use the clockin time for auto-clockout if it's in the future"
[clockin future ""]
[clockin future "" ""]
[printf "%s-%s" futurestr futurestr]
]

View File

@ -155,7 +155,8 @@ data TimeLogEntry = TimeLogEntry {
tlsourcepos :: SourcePos,
tlcode :: TimeLogCode,
tldatetime :: LocalTime,
tlcomment :: String
tlaccount :: String,
tldescription :: String
} deriving (Eq,Ord,Typeable,Data)
data HistoricalPrice = HistoricalPrice {

View File

@ -30,6 +30,7 @@ module Hledger.Read.JournalReader (
datetimep,
codep,
accountnamep,
modifiedaccountname,
postingp,
amountp,
amountp',

View File

@ -50,6 +50,7 @@ where
import Control.Monad
import Control.Monad.Except
import Data.List (isPrefixOf, foldl')
import Data.Maybe (fromMaybe)
import Test.HUnit
import Text.Parsec hiding (parse)
import System.FilePath
@ -58,7 +59,7 @@ import Hledger.Data
-- XXX too much reuse ?
import Hledger.Read.JournalReader (
directive, historicalpricedirective, defaultyeardirective, emptyorcommentlinep, datetimep,
parseJournalWith, getParentAccount
parseJournalWith, modifiedaccountname
)
import Hledger.Utils
@ -104,8 +105,9 @@ timelogentry = do
code <- oneOf "bhioO"
many1 spacenonewline
datetime <- datetimep
comment <- optionMaybe (many1 spacenonewline >> liftM2 (++) getParentAccount restofline)
return $ TimeLogEntry sourcepos (read [code]) datetime (maybe "" rstrip comment)
account <- fromMaybe "" <$> optionMaybe (many1 spacenonewline >> modifiedaccountname)
description <- fromMaybe "" <$> optionMaybe (many1 spacenonewline >> restofline)
return $ TimeLogEntry sourcepos (read [code]) datetime account description
tests_Hledger_Read_TimelogReader = TestList [
]

View File

@ -1,12 +1,22 @@
# a timelog session is parsed as a similarly-named transaction with one virtual posting
hledgerdev -f - print
<<<
i 2009/1/1 08:00:00 something
o 2009/1/1 09:00:00
i 2009/1/1 08:00:00
o 2009/1/1 09:00:00 stuff on checkout record is ignored
i 2009/1/2 08:00:00 account name
o 2009/1/2 09:00:00
i 2009/1/3 08:00:00 some:account name and a description
o 2009/1/3 09:00:00
>>>
2009/01/01 * 08:00-09:00
(something) 1.00h
() 1.00h
2009/01/02 * 08:00-09:00
(account name) 1.00h
2009/01/03 * and a description
(some:account name) 1.00h
>>>2
>>>= 0