A timetrap compatible command line time tracking application.
If you're a rust programmer you can do
cargo install tiempo
Ir if you use archlinux, there's a tiempo-git
package in the AUR.
First of all, you can abbreviate all commands to their first letter, so t in
and t i
are equivalent.
Register the start of an activity in the default timesheet with:
t in 'Doing some coding'
which sets the activity's start time to the current time. Later when you're done use
t out
to mark it as finished. If you forgot to start the activity before you can do so with:
t i --at '20 min ago'
the same applies for t out
.
Edit an entry with
t edit [options]
where the options are
-i, --id <id:i> Alter entry with id <id> instead of the running entry
-s, --start <time:qs> Change the start time to <time>
-e, --end <time:qs> Change the end time to <time>
-a, --append Append to the current note instead of replacing it
the delimiter between appended notes is
configurable (see configure)
-m, --move <sheet> Move to another sheet
You can remove an entry with
t kill --id 123
or an entire timesheet with
t kill somesheet
check bellow to see how to get the ids.
At any point in time you can check your time spent in the current or other timesheet with:
t display [options] [SHEET | all | full]
the available options are
-v, --ids Print database ids (for use with edit)
-s, --start <date:qs> Include entries that start on this date or later
-e, --end <date:qs> Include entries that start on this date or earlier
-f, --format <format> The output format. Valid built-in formats are
ical, csv, json, ids, factor, and text (default).
Check the docs on defining custom formats bellow.
-g, --grep <regexp> Include entries where the note matches this regexp
Some shortcuts available are:
today
- Display entries that started today
t today [--ids] [--format FMT] [SHEET | all]
yesterday
- Display entries that started yesterday
t yesterday [--ids] [--format FMT] [SHEET | all]
week
- Entries of this week so far. The default start of the week is Monday
(configurable).
t week [--ids] [--end DATE] [--format FMT] [SHEET | all]
month
- Entries of this month or a specified one.
t month [--ids] [--start MONTH] [--format FMT] [SHEET | all]
You can organize your activities in different timesheets by first switching to an existing one, then starting an activity:
t sheet somename
t in 'some activity'
which will also create the timesheet if it doesn't exist.
List all existing timesheets using
t list [all]
(defaults to not showing archive timesheets with names preceded by an underscore)
You can archive entries from a timesheet using:
t archive [--start DATE] [--end DATE] [SHEET]
which defaults to archiving all entries in the current sheet, or you can be more specific using these options:
-s, --start <date:qs> Include entries that start on this date or later
-e, --end <date:qs> Include entries that start on this date or earlier
-g, --grep <regexp> Include entries where the note matches this regexp.
This subcommand will move the selected entries to a hidden timesheet named
_[SHEET]
(the name of the timesheet preceded by an underscore).
It is possible to access directly the sqlite database using
t backend
tiempo
keeps a config file, whose location you can learn usign t configure
.
It is also possible to edit the config file in-place passing arguments to
t configure
like this:
t c --append-notes-delimiter ';'
it will print the resulting config file. Beware that it wont keep comments added to the file.
Some arguments accept a time as value, like t in
's --at
or t d --start
.
These are the accepted formats:
Something similar to ISO format will be parsed as a time in the computer's timezone.
2021-01-13
a date2019-05-03 11:13
a date with portions of a timeISO format with offset or UTC will be parsed as a time in the specified
timezone. Use Z
for UTC
and an offset for everything else
2021-01-13Z
2005-10-14 19:20:35+05:00
something that looks like an hour will be parsed as a time in the current
day in the computer's timezone. Add Z
or an offset to specify the timezone.
11:30
23:50:45
(with seconds)some human times, for now restricted to time ago:
an hour ago
a minute ago
50 min ago
1h30m ago
two hours thirty minutes ago
You can implement your own formatters for all subcommands that display entries
(like t display
, t week
etc.). It is as easy as creating an executable file
written in any programming language (interpreted or compiled) and placing it in
a path listed in the config value for formatter_search_paths
.
This executable will be given as standard input a csv stream with each row
representing a time entry with the same structure as the csv
formatter output.
It will also be given a command line argument representing user settings for
this formatter stored in the config file and formatted as JSON.
Suppose we have this config file:
```toml databasefile = "/home/user/.config/tiempo/database.sqlite3" roundinseconds = 900 appendnotesdelimiter = " " formattersearchpaths = ["/home/user/.config/tiempo/formatters"] defaultformatter = "text" autosheet = "dotfiles" autosheetsearchpaths = ["/home/user/.config/tiempo/autosheets"] autocheckout = false requirenote = true weekstart = "Monday"
[formatters.earnings] hourly_rate = 300 currency = "USD" ```
then we can create the earnings
formatter by placing the following file in
/home/user/.config/tiempo/formatters/earnings
:
```python
import sys import json import csv from datetime import datetime, timezone from datetime import timedelta from math import ceil
config = json.loads(sys.argv[1])
reader = csv.DictReader( sys.stdin, fieldnames=['id', 'start', 'end', 'note', 'sheet'], )
total = timedelta(seconds=0)
for line in reader: start = datetime.strptime(line['start'], '%Y-%m-%dT%H:%M:%S.%fZ')
if not line['end']:
end = datetime.utcnow()
else:
end = datetime.strptime(line['end'], '%Y-%m-%dT%H:%M:%S.%fZ')
total += end - start
hours = total.totalseconds() / 3600 earnings = hours * config['hourlyrate'] currency = config['currency']
print(f'You have earned: ${earnings:.2f} {currency}') ```
Now if you run t display -f earnings
you will get something like:
You have earned: 2400 USD
You need rust, then clone the repo and simply run
cargo test
to check that everything is working, and then
cargo build --release
to have a binary at target/release/t
that you can then move to a
directory in your PATH
or use it by its absoulte or relative paths.
Run
t --help
to see the options.
When developing I prefer not to mess with my own database, so I use this .env
file:
export TIMETRAP_CONFIG_FILE=/absolute/path/to/repo/dev_config.toml
PS1="$ "
and when I want to test some commands against such config file I just source it:
source .env
cargo run -- in 'hola'
To timetrap for existing. It is the tool I was looking for and whose design I took as reference, keeping compatibility when possible.