tt: Simplest and fastest time tracking


When it comes to tracking time on activities precisely, one has to start coping with time tracking applications. I was not able to find a simple solution, all the options were UI-based, feature-full and annoying to use. Then I started searching for command-line options, where the situation is much more clean, but still, too many features.

Finally I came up with tt: a simple script on 6 lines of code. In this article I name some other options and inspirations you may use, and the script itself with installation steps.

Example:

tt hello
... some time
tt writing blog
... some time
tt lunch 

Existing solutions

There are several existing command-line time tracking applications you may consider:

  • Tiny Time tracker feature-full (start, stop, pause, unpause, export…), npm package
  • ctt, which lacks proper documentation, written Python
  • wtt, notion of “project” (new, start, stop), written in Go - this one is pretty simple
  • ti, notion of “project” (on project, finish), very simple, written in Python
  • timetrap, notion of sheets, projects, in and out, written in Ruby
  • timed, actions of start, stop, super simple, line-based data file format (no JSON), written in Python
  • utt, only one action of “add”, super simple, line-based data file format (no JSON), written in Python

As the complexity is going to simpler and simpler solutions, utt and timed have nice text-based line-oriented data files. The last one: utt, goes to extreme of having only one action you can make: add a new activity record. In the morning, you add action hello, to your time log, saying, you have started working. Then, when you finish you add what have you done. And the time-difference is the duration. Simple.

tt: super simple time tracking script

To me, all of the solutions seemed over complicated. I neede something, which would be so simple, that I would not be bothered to use it. Otherwise, it would not make much sense to have time tracking installed, but not using it.

I was inspired a lot by utt and this answer on stackoverflow. Main idea is the same, you say hello as a start. Then, you say what you have done. Time difference is duration of activity. If you go out for a lunch, you say lunch and it will be just another activity in your list. If you stay with consistent naming (where bash completion and dmenu will help), you are done.

Script is as follows:

#!/bin/sh

touch ~/.tt
timestamp=$(date '+%s')
isodate=$(date --iso-8601=seconds --date "@${timestamp}")
echo "${timestamp},${isodate},${1}" >> ~/.tt

What it does is:

  1. make sure the data file is present
  2. timestamp= seconds since epoch
  3. isodate= same value but in ISO8601 format (with offset timezone)
  4. save this data into data file in most simple way, append a record

Example of data file:

cat ~/.tt 
1587283885,2020-04-19T09:30:25+02:00,hello
1587293664,2020-04-19T12:54:24+02:00,writing blog
1587298716,2020-04-19T14:18:36+02:00,lunch

This would correspond to

9:30 |-------writing blog----| 12:54 |----lunch---| 14:18 

Installation

Copy and paste:

#!/bin/sh

touch ~/.tt
timestamp=$(date '+%s')
isodate=$(date --iso-8601=seconds --date "@${timestamp}")
echo "${timestamp},${isodate},${1}" >> ~/.tt

to ~/.local/bin/tt and make it executable:

chmod a+x ~/.local/bin/tt

If your PATH does not include the ~/.local/bin, you may need to alter ~/.bashrc and add it:

PATH=$PATH:$HOME/.local/bin

but usually this is already done. Try command-line:

tt test

And see the resulting data file:

cat ~/.tt
1587283885,2020-04-19T09:30:25+02:00,test

Completion for bash

Writing same activities again and again would be tedious. Bash completion (the <tab><tab> thing) will help. Copy and paste:

#!/usr/bin/env bash

shopt -s progcomp                                                               
tt_complete() {                                                              
  local partial
  COMPREPLY=()
  partial=${COMP_WORDS[COMP_CWORD]}
  COMPREPLY=($(compgen -W '$(echo ',,hello' | cat - ~/.tt | cut -d',' -f 3 | tail -n 10 | sort -u)' -- $partial))
  return 0
}                                           
complete -F tt_complete -o dirnames tt

to ~/.tt_completion. Completion script is adapted from timed.

Alter your ~/.bashrc to load the script:

. $HOME/.tt_completion

Now you can tab-complete your recent existing activities.

Script for dmenu

To have a reasonable productivity with tt, install dmenu, its a must(!). On Ubuntu:

sudo apt-get -y install suckless-tools 

Copy and paste the dmenu version tt_dmenu:

#!/bin/sh

activities="$(echo ',,hello' | cat - ~/.tt | cut -d',' -f 3 | tail -n 10 | sort -u)"
activity=$(printf '%s\n' "${activities}" | dmenu)

if [ -z $activity ]; then
 exit
fi

touch ~/.tt
timestamp=$(date '+%s')
isodate=$(date --iso-8601=seconds --date "@${timestamp}")
echo "${timestamp},${isodate},${activity}" >> ~/.tt

into ~/.local/bin/tt_dmenu and chmod a+x ~/.local/bin/tt_dmenu.

Then just bind some hot-key in you window manager to activate the menu (I use ctrl-alt-a):

Configuration of keyboard shortcuts in lxqt
Configuration of keyboard shortcuts in lxqt

And the resulting dmenu:

tt: dmenu version showing options to be completed
tt: dmenu version showing options to be completed