Contents
This is a timewarrior extension for generating a report providing a balance between hours your worked and hours you have planned to work. This primarily is intended for users that have a flexible work hours regime and want to keep track of the balance between allotted time (hours to worked) and time actually spent (worked hours).
Below is an example of a call to the extension:
$ timew bal :week Start: Mon Oct 4 00:00:00 2021 End: Mon Oct 11 00:00:00 2021 Tag Spent Allotted Balance ─────────────────────────────── work 36:57 40:00 -4:03 study 11:00 10:00 +1:00 ─────────────────────────────── TOTAL 47:58 50:00 -3:02
And below is the content of the configuration file for such example:
# Hours for the "work" tag work { # Periodic configuration from 2021-10-01 { mon 11:00 tue 9:00 wed 5:30 thu 6:30 fri 8:00 except 2021-10-12 "National holiday" } # Individual entries for adjustment 2021-10-01 8:00 "Adjustment" } # Hours for the "study" tag study { from 2021-10-01 { mon 2:00 tue 2:00 wed 2:00 thu 2:00 fri 2:00 } }
There are no extra dependencies besides Python 3 for running this extension.
As such, you can just add a script in your timewarrior extensions directory
(usually ~/.timewarrior/extensions/
) that just runs
timewarrior_balance/balance.py.
If you are on a regular Unix machine, we provide a wrapper script (balance.sh) that can be simply be symlinked:
$ ln -s $(realpath balance.sh) ~/.timewarrior/extensions/balance
You can also install the package with pip
and add a script in the
extensions directory to call python -m timewarrior_balance
:
$ pip install --user timewarrior-balance $ echo "python -m timewarrior_balance" > ~/.timewarrior/extensions/balance $ chmod a+x ~/.timewarrior/extensions/balance
Considering that the extension is installed in timewarrior's extension
directory as a script named balance
and that you have already provided a
configuration file, it is possible to call the
extension to generate the report by calling timew balance
. It is also
convenient to use the abbreviated form timew bal
for cases when there are
no conflict with other installed extensions:
$ timew bal Start: Tue Jan 2 00:00:00 0001 End: Mon Oct 12 00:00:00 2021 Tag Spent Allotted Balance ─────────────────────────────── work 48:30 56:00 -8:30 study 11:00 12:00 -1:00 ─────────────────────────────── TOTAL 59:30 68:00 -9:30
Bellow is an example of a report for the current week:
$ timew bal :week Start: Mon Oct 11 00:00:00 2021 End: Mon Oct 18 00:00:00 2021 Tag Spent Allotted Balance ─────────────────────────────── work 4:30 32:00 -27:30 study 1:00 10:00 -9:00 ─────────────────────────────── TOTAL 5:30 42:00 -36:30
It shows that I still have to spend 27.5 hours and 9 hours on work and studies, respectively (let's hope this is the beginning of the week 😛).
We can also use dates explicitly. Below is the same report using dates:
$ timew bal 2021-10-11 to 2021-10-17 Start: Mon Oct 11 00:00:00 2021 End: Mon Oct 18 00:00:00 2021 Tag Spent Allotted Balance ─────────────────────────────── work 4:30 32:00 -27:30 study 1:00 10:00 -9:00 ─────────────────────────────── TOTAL 5:30 42:00 -36:30
The interval used by the report is parsed by timewarrior, so you can use anything that is recognized by timewarrior.
The report will count how much time is allotted and how much has been spent
for each configured tag in the interval of the report. The extension uses the
interval the user provided to the timew
command (which is parsed directly
by timewarrior
itself). If none is passed, like in the case above, then it
will default to be from 0001-01-02
until the date-time for when the report
was called.
The interval is closed at the beginning and open (i.e. exclusive) at the end. The amount of spent time is done inside that interval by summing up each track record filtered by Timewarrior. Note that time that is still being tracked is also taken into account.
By default, timewarrior-balance
uses a rounded interval for calculating the
allotted time: the start date-time is rounded down to midnight of its
previous day and the end date-time is rounded up to midnight of its next day.
If that is not desired, you can set round_interval = no
in the
configuration file.
In order to use this extension, you need to create a configuration file named
balance.conf
and place it under your timewarrior data directory (usually
~/.timewarrior/
). This configuration file is were you declare the hours
you need to spend on your activities.
The configuration file is composed by a series of blocks or variable assignments.
- Each block is a configuration for a tag you want to track. It will be explained in detail later.
- A variable assignment is a line in the format
<varname> = <value>
. Currently, the only variable interpreted bytimewarrior-balance
isround_interval
, but others might be added in the future.
The example below shows the content a configuration file with two empty blocks:
# Everything from the "#" to the end of line is considered to be a comment work { # This is an example of a configuration block to tracking hours for the # "work" tag } "tag with multiple words" { # You can use double quotes for tags with multiple words }
A block has the form <tag> { <content> }
, that is, it is defined with the
name of the tag you want to track followed by the content embraced by a pair
of opening and closing braces.
<tag>
can be a single word as the tag name or a string enclosed by double-quotes, which is useful when the tag name contains spaces or is one of the reserved keywords of balance's configuration file. You can also use the token__untagged__
in order to provide configuration for untagged timewarrior records.<content>
contains the configuration for the referred tag and may have two types of things:- Pediodic blocks, where you can define the time allotted for each day of the week;
- Individual date entries, which specify allotted times for a specific day.
Below are some examples of periodic blocks:
"study music" { from 2021-10-02 { # I'll dedicate 1 and 2½ hours to study music on Mondays and # Wednesdays, respectively mon 1:00 wed 2:30 } # I will dedicate a little more time to the activity in December from 2021-12-01 to 2022-01-01 { mon 1:00 wed 2:30 fri 2:00 } } work { # Part-time job from 2021-01-01 { mon 5:00 tue 4:00 wed 6:00 thu 5:00 } # Got a full-time job in April from 2021-04-15 { mon 8:00 tue 8:00 wed 8:00 thu 8:00 fri 8:00 except 2022-04-07 "Some national holiday" except 2022-04-20 to 2020-04-27 "Got some vacations and got back on the 27th" } }
When calculating the amount of allotted time for each tag, based on the report's start and end date, the extension calculates the number of matches possible for each rule and adds the expected time.
Below is a more formal-like description of the format.
A periodic block has the form
from <start-date> [to <end-date>] { <rules> }
.<start-date>
and<end-date>
define the time interval for which the rules defined in<rules>
have effect. The format of a date isYYYY-MM-DD
, defining the year, month and day, respectively. Note that the interval is inclusive on<start-date>
and exclusive on<end-date>
.The end date is optional. If omitted, it defaults to (i) the start date of the next periodic block or (ii) the end date of the report if this is the last periodic block of the tag block. You can use
end of time
in order to explicitly have the effect of the latter (useful when the periodic block is not the last one).<rules>
is a list with each entry being one of two things:a pair in the format
<weekday> <hours>
, representing the amount of time allotted for a certain day of the week.<weekday>
must be one of:mon
,tue
,wed
,thu
,fri
,sat
andsun
.<hours>
is defined by a number of hours optionally followed by:
and a number of minutes. Examples:5
,2:15
,7:00
.
an entry in the format
except <start-date> [to <end-date>] [<note>]
denoting an exception to the block's period. The<end-date>
is optional and defaults to the next date from<start-date>
. Those dates follow the same format and interval semantics as for the block's interval. An optional<note>
string enclosed by double-quotes is allowed to describe the exception.Each exception entry represents a date interval where the rules do not apply and can be used, for example, to record holidays and vacations.
Besides describing periodic rules for allotted time, it is also possible to specify allotted time for specific date via date entries. This is useful to make adjustments.
A date entry have a very simple format: <date> <hours> [<note>]
:
<date>
is a date in the formatYYYY-MM-DD
.<hours>
is in the same format as for hours in the rules of periodic blocks. The value of<hours>
does not replace the allotted time for the day. Instead, it might be a positive or negative value, adding to or subtracting from the time for the day.<note>
is an optional string enclosed by double-quotes that describes the entry.
Below are some examples of uses of date entries:
work { from 2021-10-01 { mon 11:00 tue 9:00 wed 5:30 thu 6:30 fri 8:00 } 2021-10-12 -8:00 "Got some time off" 2021-12-15 +2:00 "Extra hours for this specific day" # Note that the plus char is optional 2021-12-24 2:00 }
This extension is released under Mozilla Public License 2.0. A copy of the license is provided in LICENSE.txt.