millis () simply returns the number of milliseconds (1/1000 of a second) that have passed since the device was last reset.
A simple, human-scale way of thinking of it is the number of seconds since midnight.
As such, it can be used as a timestamp; at a very simple level a higher millis value will have occurred later than a lower millis value.
Subtracting the smaller from the larger will give the number of milliseconds that have elapsed between the two events.
I just had to pick my jaw back up after reading that last line because You made it.
Always always subtract the start time from the end (or current) time to get the elapsed time, same as a clock. If my start hour is 11 and my end hour is 2 then by unsigned base-12 math 2 - 11 = 3. Binary is another base and unsigned math works the same for the 32-bit unsigned long that millis() returns.
Rollover of millis() takes 49.7-some days.
If you use micros() instead of millis() then rollover takes a little over 90 minutes.
Do the always rule and rollover is not a problem. Same code handles all cases.
Mr.Dropsy -- there is no need to use long instead. All that does is break the algorithm.