Convert time to seconds

I need to convert a timecode to seconds and initially I used the Split Text plugin to separate by colon and then * 60 the first segment and add the second segment. This was great for something like 9:32 (9 minutes, 32 seconds) but I realised my folly when I received time in hours so 11:32:12 (11 hours, 32 minutes, 12 seconds) is treated as 11:32.

I thought I could use the var to calculation action and do SECOND(inputTime) where inputTime = 11:32:12 but... I guess I don't grasp the use of that function properly.

So, what's the best way to solve this?

I'm pretty sure SECOND() just returns the seconds of the time it receives as input: 11:32:12 would get you 12. There are probably 500 ways to do this, but if you wanted an all-Keyboard Maestro solution (no shell, no AppleScript), you could do this...

time in seconds.kmmacros (4.5 KB)

If your durations can have varying numbers of digits, you'd have to add some logic to split properly based on string length, but it wouldn't be hard. This solution uses Keyboard Maestro's built-in support for array variables with custom delimiters—I used the colon to split the time into its pieces, then multiply and add each piece to get the total.

If you wanted to use the shell, you can do it in a one-liner shell script, using the same principle (split on the colon and multiply and add):

echo "11:32:12" | awk -F: '{ print ($1 * 3600) + ($2 * 60) + $3 }'

Note the shell solution isn't all mine—I always forget the format when using awk relative to the brackets and print, so I had to search for the proper usage pattern :).

-rob.

4 Likes

I didn't know Keyboard Maestro has built-in support for splitting with custom delimiters; I don't need that plugin at all. I was able to get it working with the incoming formats I need to deal with like 0:46, 1:23, 10:34, 1:23:09 by using a filter set to Character Count with an if to detect if hours exist. Works brilliant! Thanks for pointing me in the right direction!

This ended up being much easier than the headache of trying to work out using date in the terminal.

2 Likes

Yep, that's probably how I would have done it, too. Glad you got it working.

-rob.

1 Like

Because of that you can take your macro a step further -- while KM arrays are indexed from 1, the 0 item is the length of the array. No need for your character counting. In pseudo-code:

if local_theDuration[0]: = 3
   -- we haz hours!
else
  -- only minutes and seconds
end if

Just for giggles, here's a method using two arrays -- your time-code and a "multiplier" array which is 3600,60,1 (i.e. the number of seconds in 1 hour, the number of seconds in 1 minute, the number of seconds in 1 second). No "If"s required:

Time Stamp Calculator (Arrays).kmmacros (4.2 KB)

The main calculation is

Local_theDuration + CALCULATE(%Variable%Local_timeCode[-Local_i]:%) * Local_multipliers[-Local_i] 

...making use of the fact that negative indices count backwards from the last item (-1) of the array.

A bit of a joke for a 2- or 3-item timestamp, but can be useful for longer arrays.

4 Likes

Haha! That's really clever! Thanks for the tip about [0]! I was wondering why arrays started from 1; using 0 as a reference to array length is neat. I'm going to go update my macro again and remove the Character Count!

1 Like

Lets take it just one step further.

As well as positive indexes, and 0, you can use negative indexes to index from the right. Thus [-1]: would give you the seconds regardless of the number of fields. Missing entries would be empty and thus invalid, but we can add a pointless, but necessary, 0 to before each component to make them legal whether they exist or not.

8 Likes

And it turns out you can include those leading 0s in the CALCULATE() function...

So if you don't need to split your time code to variables for later use, want to squeeze every ounce of performance from your macro, and don't mind an overflowing Calculation field:

Time Stamp Calculator (Arrays) v2.kmmacros (2.9 KB)

...where the calculation is

CALCULATE(0%Variable%Local_timeCode[-3]:%) * 3600 + CALCULATE(0%Variable%Local_timeCode[-2]:%) * 60 + CALCULATE(0%Variable%Local_timeCode[-1]:%)
5 Likes