Как спать до следующего воскресенья

Как я могу спать до следующего воскресенья, используя boost? Могу ли я преобразовать объект boost::gregorian::date в то, что может обрабатывать boost::this_thread::sleep_until? Возможно ли это?

#include <boost/date_time.hpp>

int main()
{
    boost::gregorian::date current_date(boost::gregorian::day_clock::local_day());
    boost::gregorian::greg_weekday next_sunday_date(boost::gregorian::Sunday);
    boost::gregorian::date next_weekday_date = next_weekday(current_date, next_sunday_date);
    // ...
}

Ответ 1

Вот что я придумал.

Обратите внимание, что я сделал код более читабельным. Это важно не только для будущего обслуживания, но и потому, что это позволит вам "увидеть лес для деревьев" - в свою очередь, позволит вам мысленно запомнить важные понятия.

По крайней мере, это помогает мне.

Изменить DyP предоставил способ использования sleep_until (который будет вести себя более точно в редких случаях, например, когда часы будут меняться во время сна).

#include <boost/date_time.hpp>
#include <boost/date_time/time_clock.hpp>
#include <iostream>

#include <thread>
#include <chrono>

int main()
{
    using namespace boost::gregorian;
    using boost::posix_time::ptime;
    using clock = boost::posix_time::microsec_clock; // or: boost::posix_time::second_clock;

    auto today       = date(day_clock::local_day());
    auto at_sunday   = greg_weekday(Sunday);
    auto next_sunday = next_weekday(today, at_sunday);

#if 1
    auto as_tm         = to_tm(next_sunday);
    auto as_time_t     = mktime(&as_tm);
    auto as_time_point = std::chrono::system_clock::from_time_t(as_time_t);

    std::this_thread::sleep_until(as_time_point);
#else
    auto duration = (ptime(next_sunday) - clock::local_time());
    auto msecs    = duration.total_milliseconds();
    std::cout << msecs << "\n";

    std::this_thread::sleep_for(std::chrono::milliseconds(msecs));
#endif
}

Смотрите компиляция на Coliru (очевидно, время ожидания)

Ответ 2

Звучит нестабильно. Что делать, если пользователь выключает компьютер или переходит в спящий режим или просто перезагружается?

Я бы сделал это одним из двух способов:

  • Добавьте запланированную задачу (или что-то вроде терминологии windows/osx)/cronjob (linux) и установите ее для запуска в воскресенье.

  • Добавьте его к автозапуску и периодически (один раз в 10/30/60 минут), проверьте это в воскресенье.

Оба способа обрабатывают перезапуск/выключение/спящий режим лучше, чем спать в течение 5 дней.