Skip to content

Parsing of .timeclock files is different from Ledger's #2365

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
the-solipsist opened this issue Apr 4, 2025 · 9 comments
Open

Parsing of .timeclock files is different from Ledger's #2365

the-solipsist opened this issue Apr 4, 2025 · 9 comments
Labels
A-WISH Some kind of improvement request or proposal. ledger-compat timeclock The timeclock file format.

Comments

@the-solipsist
Copy link
Collaborator

the-solipsist commented Apr 4, 2025

This is a valid timeclock file for ledger (and presumably emacs):

i 2025-04-04 14:40:00 Kitchen:Timer:1   	Coffee
i 2025-04-04 14:40:00 Work:Consultancy:AcmeCorp:2   	Brief note
i 2025-04-04 14:40:00 Work:Consultancy:AcmeCorp:3   	Briefer note
i 2025-04-04 14:40:00 Work:Consultancy:AcmeCorp:4   	Briefer note
o 2025-04-04 19:09:55 Work:Consultancy:AcmeCorp:3
o 2025-04-04 19:09:55 Kitchen:Timer:1

However, this file cannot be parsed by hledger:

Expected a timeclock o entry but got i.
Only one session may be clocked in at a time.
Please alternate i and o, beginning with i.

hledger presumably does this because a o [date-time] entry by itself is ambiguous if there are multiple i entries: Which of the multiple i entries are you trying to close?

ledger enforces 2 rules:

  1. If there are multiple i consecutive entries, then the o entry must disambiguate by mentioning the account.
  2. There cannot be multiple i consecutive entries for the same account.

hledger ought to do the same unless there are compelling reasons not to.

@reesmichael1
Copy link
Collaborator

See #2362 merged yesterday :)

@simonmichael
Copy link
Owner

simonmichael commented Apr 4, 2025

Specifically, hledger's o with no account name closes the most recent (by time) unclosed i. In my testing I thought that's what Ledger does. more details

@simonmichael simonmichael added A-WISH Some kind of improvement request or proposal. timeclock The timeclock file format. ledger-compat labels Apr 4, 2025
@the-solipsist
Copy link
Collaborator Author

That's the fastest ever fixing of a bug that I've seen: it was fixed even before it was reported!

I ran into this ambiguity today when improving my timer helper script. Two other plaintext time trackers (https://github.com/nikolassv/bartib) and (https://github.com/jotaen/klog) don't allow multiple open tasks, while some (like https://github.com/GothenburgBitFactory/timewarrior) allow it.

But, yes, I should have checked #2141 and #2142 before opening this issue.

Specifically, hledger's o with no account name closes the most recent (by time) unclosed i. In my testing I thought that's what Ledger does. #2142 (comment)

Here's what I found:

❯ tail -n5 ~/.hours.timeclock
i 2025-04-04 14:40:00 Work:Consultancy:AcmeCorp:2   	Brief note
i 2025-04-04 14:40:00 Work:Consultancy:AcmeCorp:3   	Briefer note
i 2025-04-04 14:40:00 Work:Consultancy:AcmeCorp:4   	Briefer note
o 2025-04-04 19:09:55 Work:Consultancy:AcmeCorp:2
o 2025-04-04 19:09:55 
❯ ledger -f ~/.hours.timeclock print
While parsing file "/home/sol/.hours.timeclock", line 120:
Error: Timelog check-out event does not match any current check-ins

@the-solipsist
Copy link
Collaborator Author

the-solipsist commented Apr 4, 2025

If there's no ambiguity, o for ledger closes the last unclosed i. If there's ambiguity (multiple unclosed is), then account name is required. Here, for instance, the last unclosed i is closed, because AcmeCorp:3 is commented out:

❯ tail -n5 ~/.hours.timeclock
i 2025-04-04 14:40:00 Work:Consultancy:AcmeCorp:2   	Brief note
#i 2025-04-04 14:40:00 Work:Consultancy:AcmeCorp:3   	Briefer note
i 2025-04-04 14:40:00 Work:Consultancy:AcmeCorp:4   	Briefer note
o 2025-04-04 19:09:55 Work:Consultancy:AcmeCorp:2
o 2025-04-04 19:09:55 
❯ ledger -f ~/.hours.timeclock print | tail -n5
2025/04/04 () Brief note
    (Work:Consultancy:AcmeCorp:2)             16195s

2025/04/04 () Briefer note
    (Work:Consultancy:AcmeCorp:4)             16195s

Had Work:Consultancy:AcmeCorp:3 not been commented out, ledger would throw an error.

@simonmichael
Copy link
Owner

Thanks for the testing @sol. I edited my comment to add a "more details" link as well.

hledger's o with no account name closes the most recent (by time) unclosed i

That's right, isn't it @reesmichael1 ? most recent by time, not most recent parsed ?

@the-solipsist
Copy link
Collaborator Author

hledger's o with no account name closes the most recent (by time) unclosed i
most recent by time, not most recent parsed ?

Ambiguity only arises in 1 case:

In case there's exactly 1 unclosed i with an account name and 1 unclosed i without an account name, the situation is ambiguous.

Ledger applies the o to the closest in line order i rather than the closest in time i.

❯ tail -n3 ~/.hours.timeclock
i 2025-04-04 14:30:00 
i 2025-04-04 14:00:00 Work:Consultancy:Acme2
o 2025-04-04 15:00:00
❯ ledger -f ~/.hours.timeclock print | tail -n5
2025/04/04 () 
    (Work:Consultancy:Acme2)                   3600s

2025/04/04 () 
    ()                                        90745s

In any other case (multiple unclosed is without account names, or multiple unclosed is with account names) it'll throw an error:

❯ tail -n3~/.hours.timeclock
i 2025-04-04 14:00:00 
i 2025-04-04 15:00:00
o 2025-04-04 19:09:55 
❯ ledger -f ~/.hours.timeclock print | tail -n4
While parsing file "/home/sol/.hours.timeclock", line 116:
Error: Cannot double check-in to the same account

@simonmichael
Copy link
Owner

simonmichael commented Apr 5, 2025 via email

@the-solipsist
Copy link
Collaborator Author

the-solipsist commented Apr 5, 2025

Sounds good.

Given that this difference between hledger and ledger could only arise in an edge case (where parse order differs from time order) of an edge case (where there's exactly 1 open i with an account and 1 open i without an account), it might not need mentioning in the manual.

@reesmichael1
Copy link
Collaborator

Sorry, I was away for a few days!

That's right, isn't it @reesmichael1 ? most recent by time, not most recent parsed ?

Yes, this should be how the new feature works. I think this thread sums up the difference well--I'll admit this particular edge case isn't something I anticipated!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-WISH Some kind of improvement request or proposal. ledger-compat timeclock The timeclock file format.
Projects
None yet
Development

No branches or pull requests

3 participants