Simplify TimeParser.

To simplify the codebase a bit, TimeParser is now:

* No longer constructed with a customisable unit map; the units are mapped to multipliers by an internal `if` statement.
* No longer a template parameterised over the types involved; the output type is now fixed to an alias of `std::uint64_t`.

This pull request also contains some unit tests for checking that TimeParser handles _valid_ time-strings.  This is not a complete test suite, as it does not check exceptions.  Currently, I'm unsure how to use Catch for exception tests, so we only check the 'valid' cases.
True; it's repeated in [PlayerPosition][].  I would argue that this should be a free function rather than in a class, though; we're in C++, not Java.

[PlayerPosition]: https://github.com/UniversityRadioYork/ury-playd/blob/ea041e3af0ef5628215e933e5e9ebc59e323fd90/src/player/player_state.cpp#L58-L62