Я работаю над приложением реального времени c ++, которое выполняет много манипуляций с датами. По соображениям производительности я сделал смещение UTC как настраиваемое значение, которое читается только один раз во время инициализации приложения. Но это вызывает проблемы в зонах DST.
Когда происходят изменения DST, переменная My UTC содержит неверное значение.
Расчет смещения каждый раз не является оптимальным решением для меня.
Так есть ли в любом случае, чтобы уведомить мою заявку об изменениях DST? Поэтому я могу рассчитать смещение только тогда, когда это нужно изменить.
Использование проекта C ++ 20 <chrono>
объекты, которые вы можете обнаружить std::chrono::system_clock::time_point
для следующего изменения смещения UTC для любой часовой пояс, а затем std::this_thread::sleep_until
тот time_point
, Когда вы просыпаетесь, делайте все, что хотите, например, вычисляйте новое смещение UTC.
Новый проект C ++ 20 <chrono>
библиотека была прототипирована и является доступна как бесплатная библиотека с открытым исходным кодом под namespace date
, Эта библиотека переносима на VS, gcc и clang и работает с C ++ 11 и более поздними версиями.
Вот эскиз того, как это может быть закодировано:
#include "date/tz.h"#include <thread>
template <class F>
void
on_utc_offset_change(date::time_zone const* tz, F f)
{
using namespace date;
using namespace std;
using namespace std::chrono;
while (true)
{
auto info = tz->get_info(system_clock::now());
f(info);
this_thread::sleep_until(info.end);
}
}
time_zone
имеет get_info(system_clock::time_point)
функция-член, которая возвращает sys_info
. sys_info
содержит всю информацию о time_zone
на определенный момент времени:
struct sys_info
{
sys_seconds begin;
sys_seconds end;
std::chrono::seconds offset;
std::chrono::minutes save;
std::string abbrev;
};
begin
а также end
участники seconds
-precision system_clock
time_point
s, которые определяют диапазон [begin, end)
для чего это time_zone
есть этот UTC offset
и сокращение (abbrev
).
Эта функция может быть вызвана так:
auto lambda = [](date::sys_info const& info)
{
using namespace date;
std::cerr << "Current UTC offset: " << info.offset << '\n';
std::cerr << "Current tz abbreviation: " << info.abbrev << '\n';
std::cerr << "Sleeping until " << info.end << " UTC\n";
};
std::thread{on_utc_offset_change<decltype(lambda)>,
date::current_zone(),
lambda}.detach();
Это отделяет thread
который работает вечно и каждый раз, когда смещение UTC изменяется для текущего компьютера time_zone
(во время запуска потока) он выводит текущую информацию, например.
Current UTC offset: -14400s
Current tz abbreviation: EDT
Sleeping until 2018-11-04 06:00:00 UTC
В качестве альтернативы вы можете запустить это для конкретного time_zone
который не установлен в данный момент на компьютере time_zone
с:
std::thread{on_utc_offset_change<decltype(lambda)>,
date::locate_zone("America/New_York"),
lambda}.detach();
Других решений пока нет …