This handler will sum (or substract) SRT-style times (SubRip format, for subtitles, eg “01:25:17,296”). This is an optimized-for-speed version, so you shouldn’t try to understand some lines, specially Nigel Garvey’s one.
to sumSrtTime(x, y, s) --> false = substract instead of sum
considering case
set text item delimiters to ","
set x to x's text items
set y to y's text items
set remX to item 1 of x
set msX to item 2 of x
set remY to item 1 of y
set msY to item 2 of y
set text item delimiters to ":"
set remX to remX's text items
set remY to remY's text items
set hX to item 1 of remX
set mX to item 2 of remX
set sX to item 3 of remX
set hY to item 1 of remY
set miY to item 2 of remY
set sY to item 3 of remY
set text item delimiters to {""}
--> calculate total milliseconds
if s then
set ms to ((hX + hY) * 3600000) + ((mX + miY) * 60000) + ((sX + sY) * 1000) + msX + msY
else
set ms to ((hX * 3600000) + (mX * 60000) + (sX * 1000) + msX) - ((hY * 3600000) + (miY * 60000) + (sY * 1000) + msY)
end if
--> following line, credits to Nigel Garvey
tell (10000000 + ms div 60000 mod 60 * 100000 + ms mod 100000) as string to ¬
return text 2 thru 3 of ((100 + ms div 3600000) as string) & ":" & text 2 thru 3 & ":" & text 4 thru 5 & "," & text 6 thru 8
end considering
end sumSrtTime
Sample usage:
set x to "04:20:06,790"
set y to "00:00:02,001"
sumSrtTime(x, y, true) --> "04:20:08,791"
sumSrtTime(x, y, false) --> "04:20:04,789"
Sorry, jj. I goofed when I posted the ‘Milleseconds to “formatted time”’ code on AS-Users the other day:
The error doesn’t show up with any of your particular values, which is why I missed it.
Just for fun, it’s possible to lose two math operations each from the additions and the subtractions like this:
to sumSrtTime(x, y, s) --> false = subtract instead of sum
considering case
-- Shorthand for - but not as fast as - jj's first block of sets.
set text item delimiters to ","
set {remX, msX} to x's text items
set {remY, msY} to y's text items
set text item delimiters to ":"
set {hX, mX, sX} to remX's text items
set {hY, miY, sY} to remY's text items
set text item delimiters to {""}
-- Start reading here:
-- Calculate individual sums/differences of milliseconds, minutes, and hours,
-- keeping too-big results for now and using the carries in subsequent steps.
if s then -- addition
set ms to msX + msY + (sX + sY) * 1000
set m to mX + miY + ms div 60000
set h to hX + hY + m div 60
else -- subtraction (y from x)
-- Add 1 minute (60000ms) to the ms result to correct in case it's negative.
set ms to msX - msY + (sX - sY) * 1000 + 60000
-- Lose the extra minute from m, but add another 60 in case it's negative.
set m to mX - miY + ms div 60000 + 59
-- Lose the extra hour here.
set h to hX - hY + m div 60 - 1
end if
-- Lose the carries while preparing the string.
tell (10000000 + m mod 60 * 100000 + ms mod 60000) as string to ¬
return text 2 thru 3 of ((100 + h) as string) & ":" & text 2 thru 3 & ":" & text 4 thru 5 & "," & text 6 thru 8
end considering
end sumSrtTime
set x to "04:20:06,790"
set y to "00:59:59,001"
sumSrtTime(x, y, true) --> "05:20:05,791"
sumSrtTime(x, y, false) --> "03:20:07,789"
In real-life use, the handler would need some plan of action for when the hours result was greater than 23 (or 99) and for when it was less than zero.
set text item delimiters to ","
set xy to text items of x & text items of y
set text item delimiters to ":"
set {hX, mX, sX, msX, hY, miY, sY, msY} to text items of (xy as string)
set text item delimiters to {""}