More accurate error reporting

Say whether the start or end times is invalid
timeDifference: return Time

We should only expose the Time type, so let's move all the
transformations inside this function.
Better digit parsing

Instead of relying on 'read' to complain, let's validate the digits
before we try to read it. This also helps unify the parsing we do,
making parseMinutes simply skip the colon if necessary and delegate to
parseDigits.