Reworked test monkey-patching using 'with' statement; Added support for 'at_time' hours

I updated 'at_time' support so that you can run a job at a particular time every hour. This was primarily done to support running jobs on the hour, regardless of when the python process is actually started. See 'test_at_time_hour' for how this is used,

As part of the changes, I also refactored the tests to use a 'with' statement to monkey-patch datetime. The 'with' statement monkey patches datetime with the provided arguments, and then restores it afterwards. This avoids the duplication of the MockDate support class.