Shortcut to log time and task data

Just on a proof-of-concept basis, I wrote a shortcut that logs time and task data input by the user. I had hoped to save the data in a Numbers spreadsheet, but that wasn’t possible, and the data is instead saved in a text file in markdown format. A few comments:

  • The user must set the location of the Time Log text file at the beginning of the shortcut, and this file must exist. The Shortcuts app will not allow the Time Log file to have an MD extension.
  • The times input by the user are assumed to be in a 12-hour format, but this may differ depending on the computer’s time settings.
  • Error checking is needed to verify the time inputs.
  • The following screenshot only shows a portion of the shortcut.

Log Time 1.shortcut (24.1 KB)

The following is a screenshot of a created Time Log viewed in a markdown editor:

I attempted to convert the markdown text created by the above shortcut to another format for easier viewing. However, the only option I could see was to use the Make Rich Text from Markdown action, but that doesn’t support markdown tables (see below).

I guess the alternatives are a markdown to html utility or possibly a simple regex. The document could then be viewed with a browser. Perhaps another option is to avoid the conversion and to format the header and user input as html. I’ll leave that for another day.

Log Time Test.shortcut (22.8 KB)

I decided that converting the markdown to another format was not a good approach. However, a reasonable use scenario might be to open the log file in a markdown editor on a periodic basis for review. Then, once this is done, a copy of the log could be saved as a PDF. On my markdown editor, this is easily done.

I edited my shortcut to use a 24-hour clock (which is my default time setting) and to perform some minimal error checking. The Shortcuts app will report an error if an entered time is invalid, and I left that as it is.

The shortcut should be edited to create the log file if it doesn’t exist. It also has a serious bug that occurs when the current time is after the start time but before the finish time. When that is the case, the shortcut assumes that the finish time is 24-hours earlier.

My revised shortcut:

Time Log.shortcut (24.3 KB)

A sample PDF created by my markdown editor from the log file::

Time Log.pdf (13.3 KB)

BTW, the markdown editor I use is part of an expensive writing app and not a good choice. However, there appear to be a number of capable markdown editors at little or no cost.

Well, it turns out that a 24-hour clock cannot be used, and this appears to be a result of the operation of the Get Dates from Input action. I rewrote the shortcut to use a 12-hour clock and added some error checking. It works as expected on my Sonoma computer.

Time Log.shortcut (24.9 KB)

The shortcuts included above can be adapted to other purposes–the following example is a simple mileage log. Instead of prompting the user with four consecutive dialogs, this shortcut uses only one:

A sample mileage log created with the shortcut and viewed in a markdown editor:

The shortcut:

Mileage Log.shortcut (24.6 KB)

The shortcuts included above all require that the user manually create the log file if it doesn’t exist. The following actions can be included in the shortcut to perform this task.

Create File.shortcut (22.5 KB)

The difference between two 24-hour-clock times on the same day can be calculated on a math basis with an AppleScript as follows:

set startTime to "12:00"
set finishTime to "15:30"
set theDurration to getDuration(startTime, finishTime) --> "3 hours 30 minutes"

on getDuration(startTime, finishTime)
	set {TID, text item delimiters} to {text item delimiters, ":"}
	set startMinutes to ((text item 1 of startTime as integer) * 60) + (text item 2 of startTime as integer)
	set finishMinutes to ((text item 1 of finishTime as integer) * 60) + (text item 2 of finishTime as integer)
	set durationHours to (finishMinutes - startMinutes) div 60
	set durationMinutes to (finishMinutes - startMinutes) mod 60
	set text item delimiters to TID
	return (durationHours as text) & " hours " & durationMinutes & " minutes"
end getDuration

I wondered if the same thing could be done with a shortcut. The answer is yes, but it’s cumbersome to the point of being unusable, although it could be kept in a separate shortcut and called that way. The following screenshot only shows a portion of the shortcut.

Time Duration.shortcut (23.4 KB)

The timing results for the AppleScript and shortcut were 0.2 and 40 milliseconds, respectively.

Just for learning purposes, I revised my Time Log shortcut to implement this approach (using a separate shortcut to calculate the time duration). There is an execution-speed penalty of about 20 milliseconds by adopting this approach, but this penalty occurs after all user input is received and has no real impact. The user must select the location of the log file at the beginning of the Time Log shortcut. Also, in the Time Log shortcut, the Run action may have to be set to the Time Duration shortcut.

The shortcuts:

Time Duration.shortcut (23.2 KB)

Time Log.shortcut (24.5 KB)

A screenshot of a time log viewed in a markdown editor:

Hi, @peavine.

It’s a very good shortcut, thank you.

I have some similar thing on AppleScript/Automator, and I just want to share my workflow, because it may be useful for you:

I use mine to track the time I spend tasks at work, and it “knows” my day starts at 6am. When I open my app here, it asks “in what I was working”, and I pick from a list of projects (like your “Lunch”, “Dinner” etc.) and it’s done.

What the app does is take the current time, for example, 8am, and understand “ah, he worked from 6am until 8am, so, 2 hours”. And let’s say by 9am I finish another project and click the app, so it calculates “ah, it’s 9am now, so he worked from 8am to 9am in this thing”, and count 1 hour.

In this way, I don’t need to type any time. It’s always NOW minus PREVIOUS ENTRY (or 6am, if it is the first task of the day).

I also added a “Project” for Lunch, that when I click, automatically add a row “Lunch: from NOW to NOW + 1 hour”. Some times I need to go back to the .TXT and fix the lunch time, but it is usually 1 hour.

I know my approach may only work for my needs, it’s just a suggestion.

Thank you,
Luiz

Luiz. Thanks for looking at my shortcut and for the description of your workflow. Your approach greatly simplifies data entry and is almost certainly more reliable. I think I might be able to edit my shortcut to work that way–I’ll give this some thought.

The shortcut included below generally works in the fashion suggested by Luiz. When run, the user is prompted to enter a job ID. The current date, start time, and finish time are also shown but should not need to be changed.

The following is a screenshot of a log created with this shortcut. I manually backdated the next to last entry to insure that the shortcut worked as desired on a new day. The first entry is needed to initialize the log and can be deleted after the second entry is created.

The following screenshot only shows a portion of the shortcut:

The shortcut:

Time Log.shortcut (26.3 KB)

Good to see my suggestion was useful for you, @peavine.

I have another thing here that may help you (not necessary to be used in this script):

  • I work from home and take my kids to school near 8am. So by 7:30 I add an entry to the log finishing some task.
  • So I drive them to school.
  • When I come back, there is a shortcut on my phone that checks if I arrived 1km from the house, and automatically add an entry to the log as “I was out from 7:30 until now”.
  • It save me the “effort” of clicking the shortcut when I sit in my desk to get back to work again.

You can do this with geolocation, but also with a NFC sticker. Just scan and it will add an entry automatically.

Again, just a suggestion. :slight_smile:

Luiz. That’s a really neat feature. I’ve always kept my computer and phone entirely separate, but I need to spend the time to get them to work together. Apple is making this even better in Sequoia.

Just to see how it might work, I rewrote my script to use a Choose from List dialog to select the Job ID. I also added a notification and a regex (from Nigel) to remove any blank lines in the log.

Time Log.shortcut (25.6 KB)

@peavine it is crazy how a simple script sometimes start becoming a little more complex and starts doing more things than expected. Hahaha. But this is the idea, to keep improving.

Adding the phone to the equation is also not necessary, but helps in some ways. Looking at the Sequoia features I think soon Apple will allow us to be more lazy. Things are getting more automatic now. It’s interesting.

1 Like

I wanted to write a shortcut that would total all times in the Duration column of the Time Log but would exclude entries with a Job ID of Personal. This got the better of me (for now). FWIW, I wrote an AppleScript which accomplishes this task, but I first had to rewrite a small portion of the Time Log shortcut to standardize the format of the Duration data (i.e. # hrs # mins).

Time Log.shortcut (26.1 KB)

The AppleScript:

use framework "Foundation"
use scripting additions

on main()
	set theFile to POSIX file "/Users/Robert/Desktop/Time Log.txt" --set to desired value
	set theString to current application's NSString's stringWithContentsOfFile:theFile encoding:(current application's NSUTF8StringEncoding) |error|:(missing value)
	set theArray to getMatches(theString) --lines with hrs and mins but not Personal or Work Total
	
	set totalMinutes to 0
	repeat with anItem in theArray
		set theHours to getMatch(anItem, ".*?(\\d{1,2}) hrs.*")
		set totalMinutes to totalMinutes + ((theHours as integer) * 60)
		set theMinutes to getMatch(anItem, ".*?(\\d{1,2}) mins.*")
		set totalMinutes to totalMinutes + (theMinutes as integer)
	end repeat
	set theHours to totalMinutes div 60
	set theMinutes to totalMinutes mod 60
	
	set theDuration to (theHours as text) & " hrs " & theMinutes & " mins"
	set logEntry to "|  | | | " & theDuration & " | Work Total |"
	set theString to theString's stringByAppendingString:(linefeed & logEntry)
	(current application's NSString's stringWithString:theString)'s writeToFile:theFile atomically:true encoding:(current application's NSUTF8StringEncoding) |error|:(missing value)
	display alert "A subtotal was added to the Time Log:" message theDuration
end main

on getMatches(theString)
	set thePattern to "(?m)(?!.*(?:Personal|Work Total)).*hrs.*mins.*"
	set theRegex to current application's NSRegularExpression's regularExpressionWithPattern:thePattern options:0 |error|:(missing value)
	set regexResults to theRegex's matchesInString:theString options:0 range:{location:0, |length|:theString's |length|()}
	set theRanges to (regexResults's valueForKey:"range")
	set theMatches to current application's NSMutableArray's new()
	repeat with aRange in theRanges
		(theMatches's addObject:(theString's substringWithRange:aRange))
	end repeat
	return theMatches
end getMatches

on getMatch(theString, thePattern)
	return theString's stringByReplacingOccurrencesOfString:thePattern withString:"$1" options:1024 range:{0, theString's |length|()} -- option 1024 is regex
end getMatch

main()

A screenshot of a test Time Log:

I was able to convert the above AppleScript to a shortcut. The Shortcuts app only has a limited number of Math and Numbers actions, but they will do a lot.

Time Log Calculate.shortcut (23.9 KB)

The above shortcut only works with the following Time Log shortcut:

Time Log.shortcut (26.1 KB)

The following is my test Time Log: