Skip to content

Repository files navigation

TimeTracker

A small always-on-top desktop widget for punching in and out, recording breaks and lunches, and reviewing your hours and overtime.

No installation, no dependencies beyond Python 3 — just tkinter and SQLite, both of which ship with Python.


Install

powershell -ExecutionPolicy Bypass -File .\Install.ps1

That creates a TimeTracker shortcut on your Desktop and asks whether you want it to start with Windows. To skip the prompt use -Startup or -NoStartup. To remove the shortcuts later (your hours are kept):

powershell -ExecutionPolicy Bypass -File .\Install.ps1 -Uninstall

You can also just double-click TimeTracker.vbs, which launches it without a console window.


Using the widget

The widget is a small pill that floats above other windows. Drag it anywhere — it remembers where you put it.

Action What happens
Click the widget Opens the action menu for whatever state you're in
Right-click Dashboard, reset position, quit
Drag Moves the widget (position is saved)

The action menu only ever offers moves that make sense right now:

Current state Menu offers
Clocked out Punch In
Working Start Break · Start Lunch · Punch Out
On break End Break
At lunch End Lunch

So the loop is: punch in → work → break → back → lunch → back → punch out. Break and lunch time is excluded from your worked hours; the widget shows a live counter while you're on one.

The pill itself shows a coloured status dot, the live figure that matters right now (hours worked today, or how long you've been on break), and a subtitle with the day's context. If you've passed your standard day it appends OT 0:45.

If the widget disappears into your wallpaper

The pill floats directly on the desktop, so a dark widget on a dark wallpaper can be hard to spot. Open the dashboard and click the small icon next to the "Hours" heading — that's the whole control, tucked out of the way rather than cluttering the widget.

Theme Good for
Midnight (default) Most wallpapers
Paper Dark or black wallpapers — light pill, dark text
High contrast Busy or photographic wallpapers — black fill, white outline
Ocean / Sunset / Violet Tinted alternatives when you just want a different look

Each row in the picker is a live miniature of the real pill, and clicking one applies it immediately — so you can see it against your actual desktop before deciding. The choice is remembered.

Themes change the widget only; the dashboard stays dark, since it's a normal window that never sits on top of your wallpaper.


The dashboard

Click the widget → View hours & timesheet (or right-click → dashboard).

Summary cards across the top: total worked, regular, overtime, holiday & leave credit, total paid, days worked, average per day, and total break + lunch time for the selected range.

Daily table: date, weekday, day type, first punch in, last punch out, break, lunch, worked, regular, overtime and credited hours. Overtime days are highlighted in amber; a day still in progress shows in green as running; marked days are tinted by type.

Footer shows expected hours for the range and whether you're ahead or behind.

Date ranges

The dashboard opens on the current pay period. Pay periods are semi-monthly:

  • 1st – 15th, which stays on screen as the default until the 20th
  • 16th – end of month, which stays on screen until the 5th of the next month

So on the 18th of a month you still see the 1–15 period; on the 3rd you still see the previous month's 16–EOM period.

Use ◀ / ▶ to step through periods, or the Range dropdown for current/previous pay period, this or last month, this week, last 7 days, today, or all time. For anything else type dates into From / To (YYYY-MM-DD or DD-MM-YYYY) and hit Apply.

Overtime

Anything worked beyond your standard day counts as overtime, computed per day. The standard day defaults to 8 hours and is editable via the hrs/day box in the dashboard toolbar — changing it recalculates history immediately, since overtime is derived rather than stored.


Holidays and leave

Right-click any day in the dashboard → Mark … as → pick a type. Select several days first (click, then shift-click) to mark a whole stretch at once — useful for a week of leave. There's also a Mark days button in the toolbar, and Mark with a note… if you want to record why.

Day type Credits by default
Public holiday 8 h
Paid leave 8 h
Sick leave 8 h
Week off 0 h

The credit follows your standard day, so setting 7.5 hrs/day makes a holiday credit 7.5 h. You can override the credit on any individual mark — set it to 4 for a half-day of leave, or 0 for an unpaid holiday.

How credited hours are counted

Credited hours are deliberately kept separate from hours worked:

  • Total worked only ever means hours you actually worked. A holiday never inflates it.
  • Holiday & leave holds the credited hours.
  • Total paid = worked + credited. This is the number for a payslip.
  • Expected counts a day if you worked it or it credits hours, so a holiday doesn't show up as a shortfall. Week off credits nothing and is excluded entirely.

If you work on a holiday, normal overtime rules apply — overtime only beyond your 8-hour standard day, exactly as on a regular day. The holiday credit still applies on top, so a 9-hour holiday shift shows 9 h worked (1 h overtime) plus 8 h credited. If you'd rather not be credited for a holiday you worked, open the mark and set its credit to 0.

To remove a mark: right-click → Clear mark, or open the dialog and hit Remove mark.


Export

Export CSV writes the visible range with a totals row, in decimal hours, ready to paste into a timesheet or spreadsheet. It includes the day type, its note, credited hours and a per-day paid total, alongside the worked figures.


Fixing mistakes

Forgot to punch out? Started lunch late? Double-click any day in the dashboard to open its raw punch list, where you can add, retime or delete individual punches. Totals recalculate immediately.

If the app finds you were still clocked in from a previous day — say the machine was shut down mid-shift — it asks on startup whether to punch you out at a specific time or keep the clock running.


Where your data lives

C:\Users\<you>\Documents\TimeTracker\timetracker.db

Set the TIMETRACKER_DIR environment variable to keep it somewhere else.

It is a plain SQLite file holding an append-only log of punches plus a small table of day marks. Every number the app shows — daily totals, breaks, overtime, period summaries — is derived from that log at display time. Nothing is precomputed, so corrections and changes to your standard day apply retroactively and correctly, and a crash can never leave a half-written total.

Note on Microsoft Store Python. If Python came from the Microsoft Store it runs sandboxed and silently redirects %LOCALAPPDATA% writes into a package cache that Windows wipes when Python is reset or uninstalled. TimeTracker therefore stores your timesheet in Documents instead, and automatically migrates any timesheet it finds in the old sandboxed location on first run.

Back it up by copying that one .db file.


Behaviour worth knowing

  • Overnight shifts are split at midnight, so a 22:00 → 03:00 shift puts 2h on one day and 3h on the next.
  • Impossible punches are ignored, not crashed on. A duplicate punch-in or an "end lunch" with no lunch started is skipped when totals are computed, so a messy log still produces sane numbers.
  • State survives restarts. The current state is replayed from the log on every launch, so closing the widget mid-shift loses nothing.
  • One instance only. A second copy refuses to start rather than have two widgets writing to the same log.

Files

File Purpose
timetracker.py Entry point, the widget, action popup, session recovery
tt_core.py Storage, state machine, time math, pay-period rules
tt_dashboard.py Dashboard, day editor, CSV export
tt_ui.py Palette and shared widget helpers
make_icon.py Generates icon.ico (no image libraries needed)
Install.ps1 Desktop / startup shortcuts
TimeTracker.vbs Console-free launcher
test_core.py Time math and pay-period checks
test_gui.py Builds every window against a throwaway database

Run the checks with:

python test_core.py && python test_gui.py

About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages