Fix scheduling of maintenance tasks in background services

Rewrite to use datetime.{datetime,timedelta} to calculate when to run
scheduled tasks and how long to wait until the next schedule point,
instead of complicated and broken "manual" calculations.

When running a task, the old code would typically schedule the next run
24 hours later (even for hourly tasks, which we fortunately don't have
any.)  For tasks running any significant amount of time, this meant the
actual running time shifted all around the clock, despite when the task
was actually configured to run.