Time tracking with Ledger
Whoever is reading this blog knows that I use Ledger-likes to track my finances. Some of you may also know that the currency is just some arbitrary name for any kind of unit. And a minority of you may also know there is special support for tracking time in the original Ledger program. This post explains how I use Ledger and a few Bash aliases to track different activities during a normal work day.
In a “regular” Ledger file you will find transactions that describe the flow of a commodity from one (or more) to another account at a certain time. There is however special support for timelog entries in the ledger program. They look similar but have special syntax to describe the start and end of a “transaction”
i 2019/03/02 00:30:20 Entertainment:Netflix
o 2019/03/02 00:35:20
which basically state what to account from i
to o
. Suppose you have a
timelog file foo.ledger
then ledger -f time.ledger bal
would give you
something like this:
9.07h Work
32.3m Mail
6.9m Admin
8.40h Development
1.69h Entertainment:Netflix
14.2m Drinking
11.9m Meetings
--------------------
11.19h
Of course, you can customize the date range and hierarchy depth. Let’s alias that to
alias wasted='ledger -f ${TIMELOG} bal -b $(date -dlast-monday +%m/%d) --depth 2'
All good. Now, adding new entries by “punching in” new lines like that above is more than just cumbersome, it’s something a simple alias could do as well. I have defined something like
alias clock-in='echo i $(date +"%Y/%m/%d %H:%M:%S") >> ${TIMELOG}'
alias clock-out='echo o $(date +"%Y/%m/%d %H:%M:%S") >> ${TIMELOG}'
where TIMELOG
points to the time.ledger
file. Once you type
$ clock-in Work:Mail
an appropriate transaction will be made. To check what’s currently going on, this alias might help:
alias clock-status='[[ $(tail -1 ${TIMELOG} | cut -c 1) == "i" ]] && { echo "Clocked IN to $(tail -1 ${TIMELOG} | cut -d " " -f 4)"; wasted; } || { echo "Clocked OUT"; wasted;}'
That all looks nice and dandy until you realize you don’t remember a particular activity you want to account you current time on. If you have used any CLI program you probably hit Tab more than twice. Wait no more, just define
function _clock_in ()
{
local cur prev
_get_comp_words_by_ref -n : cur
local words="$(cut -d ' ' -s -f 4 ${TIMELOG} | sed '/^$/d' | sort | uniq)"
COMPREPLY=($(compgen -W "${words}" -- ${cur}))
__ltrim_colon_completions "${cur}"
}
complete -F _clock_in clock-in
and you are all set to complete the timelog entry while you clock in. You could write more elaborate logic in an appropriate scripting language but that’s an exercise for the reader.