Как обойтись без бесконечного цикла?
К примеру можно использовать таймер, после указания времени во сколько разбудить мы высчитываем через сколько данный таймер должен сработать и запускаем его. Как только таймер сработал - будим человека.
Бесконечный цикл все равно будет, либо ты его напишешь либо его организует библиотека (какой-нибудь асинхронный фреймворк типа react, если что твой ответ можно найти в нем).

В каждом конкретном случае реализовывать нужно будет правильно по своему

С часами все просто - нужно не раз в секунду проверять время, а взять самый короткий интервал и вычислить, сколько до него ждать (время действия минус текущее время) и просто одной командой выставить sleep.