{"id":36445672,"url":"https://github.com/thefenriswolf/ttt","last_synced_at":"2026-01-11T22:42:52.196Z","repository":{"id":213768585,"uuid":"734870645","full_name":"thefenriswolf/ttt","owner":"thefenriswolf","description":"Time Tracker Tool written in Golang","archived":false,"fork":false,"pushed_at":"2024-06-10T16:46:59.000Z","size":50,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2024-06-21T02:13:54.647Z","etag":null,"topics":["cli","golang","pta","time-tracker"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/thefenriswolf.png","metadata":{"files":{"readme":"README.org","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-12-22T21:37:17.000Z","updated_at":"2024-01-04T21:30:15.000Z","dependencies_parsed_at":"2024-03-07T17:01:00.418Z","dependency_job_id":"696f719d-ea13-4f54-adc3-bd02ef7b97ab","html_url":"https://github.com/thefenriswolf/ttt","commit_stats":null,"previous_names":["thefenriswolf/ttt"],"tags_count":5,"template":false,"template_full_name":null,"purl":"pkg:github/thefenriswolf/ttt","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thefenriswolf%2Fttt","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thefenriswolf%2Fttt/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thefenriswolf%2Fttt/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thefenriswolf%2Fttt/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/thefenriswolf","download_url":"https://codeload.github.com/thefenriswolf/ttt/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thefenriswolf%2Fttt/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28326144,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-11T22:11:01.104Z","status":"ssl_error","status_checked_at":"2026-01-11T22:10:58.990Z","response_time":60,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cli","golang","pta","time-tracker"],"created_at":"2026-01-11T22:42:51.585Z","updated_at":"2026-01-11T22:42:52.183Z","avatar_url":"https://github.com/thefenriswolf.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"[[file:https://github.com/thefenriswolf/ttt/blob/main/resources/ttt_icon.svg]]\n\n* ttt\n=ttt= is a cli time tracker tool written in GoLang, using a plain text file as it's database.\n\n* Table of Contents :TOC:QUOTE:\n#+BEGIN_QUOTE\n- [[#ttt][ttt]]\n- [[#installation][Installation]]\n  - [[#via-go][Via Go]]\n  - [[#manual][Manual]]\n- [[#usage][Usage]]\n  - [[#getting-started][Getting started]]\n  - [[#create-a-journal-file][Create a Journal File]]\n  - [[#edit-journal-settings][Edit Journal settings]]\n  - [[#organize-and-clean-the-database][Organize and clean the database]]\n  - [[#print-reports][Print Reports]]\n  - [[#export-reports-as-pdf][Export Reports as PDF]]\n  - [[#plot-reports-not-implemented-yet][Plot reports (NOT IMPLEMENTED YET)]]\n  - [[#print-help][Print help]]\n- [[#credits][Credits]]\n  - [[#dependencies][Dependencies]]\n  - [[#similar-projects][Similar Projects]]\n- [[#license][License]]\n- [[#the-story-behind-this-program][The story behind this program]]\n#+END_QUOTE\n\n* Installation\n** Via Go\n#+begin_src bash\ngo get github.com/thefenriswolf/ttt\n#+end_src\n** Manual\n*** Make\n#+begin_src bash\ngit clone https://github.com/thefenriswolf/ttt.git\ncd ttt\nmake PLATTFORM # linux, osx, windows\n\nsudo mv ttt_PLATTFORM_amd64 /usr/local/bin/ttt # optional\n#+end_src\n*** Nix\n#+begin_src bash\ngit clone https://github.com/thefenriswolf/ttt.git\ncd ttt\nnix-shell shell.nix\nnix-build\n#+end_src\n* Usage\n** Getting started\nCreate a database file, this is always a =CSV= file.\n*!Currently you can't change field order at runtime!*\nThis may be implemented in the future.\n\nThe following defaults apply:\n- delimiter: ' ' (single space)\n- comment: #\n- date format: DD.MM.YYYY\n- time format: HHMM\n\nAs you can tell from the example database below, the entries don't have to be in chronological order.\n=ttt= will sort them and group them at runtime.\n#+begin_src csv\n# date startTime endTime Activity\n\n20.09.2023 1400 1700 $Jobname\n20.12.2023 1400 1700 $Jobname\n20.09.2023 1400 1700 $Jobname\n20.07.2023 1400 1700 $Jobname\n20.01.2023 1400 1700 $Jobname\n#+end_src\n\n** Create a Journal File\n=ttt= will create a template file at the current directory.\n#+begin_src bash\nttt init\n#+end_src\n\n** Edit Journal settings\nThe header of your journal file contains setting fields.\n\nHere you can set things like:\n- =hours=: your weekly workhours\n- =delimiter=: By default =ttt= uses a single space ' '\n- =datefmt=: By default =ttt= uses *DD.MM.YYYY*\n- =timefmt=: By default =ttt= uses *HHMM*\n\n** Organize and clean the database\n#+begin_src bash\nttt -f somefile.csv print \u003e\u003e newfile.csv\n#+end_src\nPrints your file to =stdout= after sorting it and removing empty lines.\n\n** Print Reports\n#+begin_src bash\nttt -f somefile.csv report\n#+end_src\nPrints a worktime report to =stdout=.\n**** Example\n#+begin_src csv\n[...]\n\n20.01.2023 1400 1700 Job\n20.02.2023 1400 1700 Job\n20.03.2023 1400 1700 Job\n20.04.2023 1400 1700 Job\n20.05.2023 1400 1700 Job\n20.06.2023 1400 1700 Job\n20.07.2023 1400 1700 Job\n20.08.2023 1400 1700 Job\n20.09.2023 1400 1700 Job\n\n[...]\n#+end_src\n\n*** By week\nThis is the default option.\n#+begin_src bash\nttt -f somefile.csv report week\n#+end_src\n**** Example\n#+begin_src csv\n[...]\n\n20.01.2023: 3h0m0s\n20.01.2023: 3h0m0s\n20.01.2023: 3h0m0s\n20.01.2023: 3h0m0s\n20.01.2023: 3h0m0s\n20.01.2023: 3h0m0s\n20.01.2023: 3h0m0s\n20.01.2023: 3h0m0s\n20.01.2023: 3h0m0s\n20.01.2023: 3h0m0s\n20.01.2023: 3h0m0s\n20.01.2023: 3h0m0s\n20.01.2023: 3h0m0s\n20.01.2023: 3h0m0s\n=========================\nSummary KW3:\n-------------------------\nWeekly sum: 42h0m0s\nWeekly overtime: 12h0m0s\n=========================\n\n[...]\n#+end_src\n\n*** By month\n#+begin_src bash\nttt -f somefile.csv report month\n#+end_src\n**** Example\n#+begin_src csv\n[...]\n\n20.12.2023: 3h0m0s\n20.12.2023: 3h0m0s\n20.12.2023: 3h0m0s\n20.12.2023: 3h0m0s\n20.12.2023: 3h0m0s\n=========================\nSummary of December:\n-------------------------\nMonthly sum: 15h0m0s\n\n[...]\n#+end_src\n\n*** By year (NOT IMPLEMENTED YET)\n#+begin_src bash\nttt -f somefile.csv report year\n#+end_src\n\n** Export Reports as PDF\n#+begin_src bash\nttt -f somefile.csv export\n#+end_src\nPrints a worktime report to a PDF file in your current directory.\n\n*** By week\nThis is the default option.\n#+begin_src bash\nttt -f somefile.csv export week\n#+end_src\n\n*** By month\n#+begin_src bash\nttt -f somefile.csv export month\n#+end_src\n\n** Plot reports (NOT IMPLEMENTED YET)\n#+begin_src bash\nttt -f somefile.csv graph\n#+end_src\nPrints a graph of your worktime to =stdout=\n\n*** By month\nThis is the default option\n#+begin_src bash\nttt -f somefile.csv graph month\n#+end_src\n\n*** By year\n#+begin_src bash\nttt -f somefile.csv graph year\n#+end_src\n\n** Print help\n#+begin_src bash\nttt --help\n#+end_src\n\n* Credits\n** Dependencies\n=ttt= depends on the following projects:\n- [[https://github.com/mpvl/unique][Marcel van Lohuizen's unique package]]\n- [[https://github.com/urfave/cli][urfave's cli package]]\n- [[https://github.com/pterm/pterm][pterm]]\n\n** Similar Projects\n- [[https://ledger-cli.org][ledger-cli]] the main inspiration for this project.\n  - yes, you can track time with ledger see [[https://bloerg.net/posts/time-tracking-with-ledger/][here]]\n\n* License\n=ttt= is [[https://github.com/thefenriswolf/ttt/blob/main/LICENSE][BSD Clause 3]] licensed.\n\n* The story behind this program\n=ttt= has been created to solve a very specific problem of mine:\n\nYou see I want to track my workhours, but I can't bring my laptop with me to work.\nOf course the company I work for has it's own fancy web-based worktime recording system.\nIt does sophisticated reports, keeps track of your days off and even handles day off requests.\n\nBut I found it to be unreliable, at least once a month it fails to record my clock-in or clock-out.\nThis can only be retroactively filled in by someone with admin privileges, which I don't have.\nSo in theory a nefarious employer could ask the admin to manipulate the database in their favor.\n\nThus I have my own offsite recordings, in the past I used to use an app on my phone for this.\nI would then export my records as a =CSV= file and process it on my computer.\n\nThis worked just fine until the app developer got greedy and locked the export button behind a *35€ (or 0.99€/mo)* paywall!\n\nAt that time I was already using =ledger-cli= for my finances and ledger can also do time tracking.\nBut writing ledger files by hand on a tiny smartphone screen is tedious.\n\nYes you can prepopulate the file with blank entries on a computer and just fill in the time on the phone or copy and paste a template every time.\n\nTrust me I tried both methods.\n\nThe blank entries method makes you search for the current date for a while and the copy and paste method falls apart when you see how bad precise text selection works on a phone.\n\nFor the uninitiated, a ledger time record looks like this:\n#+begin_src ledger\ni 2023/12/20 05:30:00 Work:$Job\no 2023/12/20 14:00:00\n#+end_src\n\nTwo lines, not too bad you'd think, what's the big deal you'd think.\n\nWell let me tell you, those 2 lines per day add up.\n\nLet's do some quick math:\n- The usual work week for most people (at least where I live) consist of 5 workdays.\n- There are 52 weeks in a year if we don't account for days off.\n- We need 2 lines per record, but realistically you want a blank line after every record to introduce at least a minimum of readability.\n#+begin_src\n5 days per week * 52 weeks per year * 3 lines per entry = 780 lines!\n#+end_src\nYou see, by December i was scrolling quite a bit to get to the bottom of a file.\nNow of course you could combat that problem by creating a new file every month but that method just does not scale if you want to calculate your overtime at the end of the year.\n\nSo I searched around for a while for project that could do the same job but with a quicker syntax.\nMost programs command syntax (like [[https://timewarrior.net][timewarrior]]) require you to be on a computer to use the program effectively.\n\nThis made me think if I couldn't write my own program, that fit my needs perfectly, bear in mind that I am not a programmer and I also don't play one on TV.\nThe best I could do were:\n- nix for my home-manager and NixOS configs\n- bash scripts that failed in spectacular ways with more bugs than features\n- python image manipulation scripts I had to write for University\n- and R statistics scripts, also for University\n\nSo here we are, I made a program that barely has enough features to be useful to me.\nI chose GoLang because I wanted it to be statically compiled and sort of fast (=ttt= spits out reports in ~20ms).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthefenriswolf%2Fttt","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fthefenriswolf%2Fttt","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthefenriswolf%2Fttt/lists"}