检测 C++ 中的 DST 更改
Posted
技术标签:
【中文标题】检测 C++ 中的 DST 更改【英文标题】:Detecting DST changes in C++ 【发布时间】:2018-12-12 18:00:20 【问题描述】:我正在开发 c++ 实时应用程序,该应用程序正在执行大量日期操作。出于性能原因,我将 UTC 偏移量设置为可配置值,在应用程序初始化时只读取一次。但它在 DST 区域中引起了问题。
当 DST 更改发生时,我的 UTC 偏移变量包含错误的值。 每次计算偏移量对我来说不是最佳解决方案。
那么无论如何要通知我的应用程序有关 DST 更改?所以我只能在需要修改的时候计算偏移量。
【问题讨论】:
您需要两个设置:地区或国家,它决定何时发生 DST 更改。以及当前时区,它定义了与 UTC 的标准时间偏移。如果 DST 生效(从第一个设置可知),则在当前本地时间(按时区计算)增加一小时。但是,一旦你完成了所有这些,然后抛出你的代码代码处理时间和时区。时间和日期比看起来要困难得多,所以我真的建议你尝试找到一个可以为你处理所有事情的库。 会有帮助吗? superuser.com/questions/294984/… 关于计算偏移量部分:可以计算下一次DST变化的时间戳并缓存。然后每次使用时间时,只需将其与缓存的时间戳进行比较。如果较低,则 DST 没有变化,如果较高,请更新您的偏移量并计算下一次 DST 变化。 【参考方案1】:使用草案 C++20 <chrono>
工具,您可以发现std::chrono::system_clock::time_point
用于任何 时区的下一个UTC 偏移更改,然后std::this_thread::sleep_until
发现time_point
。当你醒来时,做任何你想做的事,比如计算一个新的 UTC 偏移量。
新的C++20草案<chrono>
库已经原型化,在namespace date
下是available as a free, open-source library。该库可跨 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
和缩写 (@987654347 )。
这个函数可能会这样调用:
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::threadon_utc_offset_change<decltype(lambda)>,
date::current_zone(),
lambda.detach();
这会分离一个永远运行的thread
,例如,每当计算机当前time_zone
(在线程启动时)的UTC偏移量发生变化时,它都会打印出当前信息。
Current UTC offset: -14400s
Current tz abbreviation: EDT
Sleeping until 2018-11-04 06:00:00 UTC
或者,您可以为特定的time_zone
运行此命令,该time_zone
不是计算机当前设置的time_zone
:
std::threadon_utc_offset_change<decltype(lambda)>,
date::locate_zone("America/New_York"),
lambda.detach();
【讨论】:
感谢您的回答。我没有升级编译器的选择。 甚至没有到 C++11?!我最诚挚的哀悼。以上是关于检测 C++ 中的 DST 更改的主要内容,如果未能解决你的问题,请参考以下文章