13 ноября 2008

Wake me up tomorrow

Функции WinAPI, которые можно использовать в качестве "будильника" - SetTimer(), WaitForSingleObject(), и прочие принимают время относительное, а не абсолютное. Нельзя сказать "Разбудите меня завтра!". Только "Пните меня через 13786 миллисекунд".

Разумный вариант - подсчитать сколько миллисекунд до заданного времени, но ничто не вечно под луной. Время может перевести пользователь, программка, синхронизирующаяся с сервером, да сама Windows, в конце концов. Так что заодно мониторим WM_TIMECHANGE и пересчитываем сколько осталось.
void SetTimerToTommorrow()
{
using namespace boost::posix_time;
using namespace boost::gregorian;

ptime Now(second_clock::local_time()), Tomorrow(Now.date() + days(1));
SetTimer(..., (Tomorrow - Now).total_milliseconds() + 1, ...);
}

4 комментария:

Анонимный комментирует...

Функции WinAPI ... принимают время относительное, а не абсолютное.
Зато функции Native API могут работать как с относительным, так и с абсолютным временем, например, NtDelayExecution

Анонимный комментирует...

Есть еще объекты ядра waitable timers (CreateWaitableTimer и т.д), из той же темы что и event, mutex и т.п.

Анонимный комментирует...

Собственно, как писал предыдущий аноним, есть ожидаемые таймеры. Их как раз можно установить на конкретную дату/время с точностью до 1 мс, если не ошибаюсь. Мало того, где-то в дебрях MSDN я натыкался на утверждение о том, что ожидаемый таймер может "тикать" на спящей (suspended) системе, а в нужное время - разбудить ее. Руками, правда, последнее пробовать не доводилось:)

Raider комментирует...

Спасибо, надо будет попробовать!