C++ 20对VisualStudio 2019版本16.10中可用的时间扩展的扩展

<chrono> 标头已经作为STL的一部分,自从C++ 11以来,在C++ 20中的变化中,有几个扩展到计时,包括对Calnordic类型、时区、跳跃秒和与格式的集成的支持。为了完成这些附加功能,需要进行大量的创新和工作;在没有开源社区的惊人支持的情况下,这么快的将这些新的C++ 20添加起来是不可能的。特别是,我要感谢联合国作出的重大贡献 马特·斯蒂芬森 , 声明回复 ,和 丹尼尔·马歇尔 帮助完成我们的实施。

null

有许多补充到 <chrono> 标题中的C++ 20的更改,这里我想强调几点。

历法类型

公共关系 GH-323:部分执行P0355R7 ,作者danielmarshall在标题中添加了一长串新的日历类型以支持日期。例如:

#include <chrono>
using namespace std::chrono;

int main() {
   year y{2021};
   year_month_day world_bee_day = May/20d/y;
   month_weekday mwd = May/Thurs[3];
   year_month_weekday world_bee_day2 = 2021/mwd;
}

这里我们创建一个 year 对象,然后使用它创建 year_month_day 代表2021年5月20日或世界蜜蜂日的对象。然后我们使用另一种形式来表示同一天,方法是 month_weekday 代表五月第三个星期四的物体(用 Thurs[3] 创造了一个 weekday_indexed 对象),然后使用该对象创建 year_month_weekday 对象,将其与整数组合 2021 它被解释为年份。

您可以看到,该库现在包括各种不同的日历类型,允许用户以各种不同的方式创建日期。这些不同形式的日期是为了非常易于使用和直观,所以用户可以选择最舒适或自然的方法给他们。

时区

对时区的认识是这项工作的另一个重要补充 <chrono> 标题,其中包括新类型(例如。, time_zone , tzdb , zoned_time )以及如何管理图书馆新发现的时区意识所需的数据的重要考虑。下面是一个显示新时区功能示例的小示例:

#include <chrono>
using namespace std::chrono;

int main() {
   const auto& my_tzdb = get_tzdb();
   const time_zone* la_tz = my_tzdb.locate_zone("America/Los_Angeles");
   auto world_nutella_day = local_days{2021y/Feb/5};
   zoned_time la_nutella_day{la_tz, world_nutella_day + 3h + 44min + 12s};
   zoned_time utc_nutella_day{"Etc/UTC", la_nutella_day};
}

这只是新添加的时区支持中包含的功能的一个小例子。该功能还支持不同时区之间的转换、“本地”时间的概念,以及由于夏时制转换而导致时区之间的转换不明确或不存在的可能性。 在本例中,我们首先获得对最新版本的引用 tzdb 对象,其中包含有关时区的数据。然后我们用它按名称查找美国/洛杉矶时区(GMT-07:00),存储一个 time_zone 指向 tzdb . 接下来,我们使用 local_days 以及上面提到的历法类型,我们可以用它们来创建一个 zoned_time 对象,该对象将特定的日期/时间(在本例中为03:44:12的世界Nutella日)与给定的时区(在本例中为美国/洛杉矶)配对。  然后我们使用美国/洛杉矶 zoned_time 创建 zoned_time 对应UTC时间,说明时区转换功能。

我们在实现中遇到的一个具体挑战是如何实际访问时区所需的数据。C++ 20标准定义了时区功能,以 IANA数据库 但是,由于MSVC的STL的大小和如何提供更新的问题,它将无法将整个数据库与其实现一起提供。当我们思考如何支持这个标准的强制特性而不让我们的客户承受荒谬的头大小增加时,我们不得不探索其他的选择。我们最终发现了 重症监护室 图书馆 作为Windows 10操作系统的一部分提供 在较新的版本(19H1及以后),并从IANA数据库本身获取数据。因此,对时区数据的更新将与通过Windows Update对操作系统的更新一起执行。虽然我们当前的实现依赖于ICU DLL在更新的操作系统版本中的可用性,但我们计划 重新审视这个问题 并研究为较旧的操作系统实现回退。虽然IANA数据库和ICU图书馆之间存在一些差异,但数据应该基本相同。

跳跃秒

我们最近的更改还包括对跟踪闰秒的支持,这主要是在MattStephanson的 GH-1671: C++ 20时钟,时钟锁,TZDB::LeAP秒秒 ,从statementreply获得有价值的输入。有了这个新的支持,您可以询问在闰秒插入或删除期间是否发生了给定的时间(有趣的事实,两者都有) 积极的 负闰秒 是可能的!)不管怎样。C++ 20还添加了几个新的时钟类型(除了 system_clock , steady_clock ,和 high_resolution_clock 其中有自C++ 11以来存在的,其中有些跃迁第二意识(如 utc_clock )而其他人不是(例如 system_clock ). 我们通过Windows注册表检测新的闰秒(在 丹·库莫的网络博客 ),因此任何新的闰秒都需要通过Windows更新来检测。

“计时”

交叉点 chrono std::format 在我们的回购中亲切地称为“CalaTAT”,将两个C++ 20个最大的特征结合在一起。“Chronat”包括对 chrono 的新类型,其格式说明符/解析标志在很大程度上类似于 strftime 的格式化代码。在格式方面,有 struct formatter 专为几乎每一个新的类型添加到chrono,使它能够无缝集成到 std::format 的接口。更多信息请参见查理·巴托的博客 std::format . 一个简单的例子 chrono 的解析和格式如下:

#include <chrono>
#include <sstream>
#include <string>
using namespace std;
using namespace std::chrono;

int main() {
   day d;
   basic_stringstream<char> sstr{"22"};
   basic_string<char> s{"%d"};
   sstr >> parse(s, d);
   cout << d << "";

   year_month_day programmers_day{January/7d/2021};
   cout << format("International Programmer’s day: {%F}", programmers_day);
}

我们首先有一个例子,解析 stringstream 变成一个 day 然后可以输出到 std::cout ,然后我们还会看到一个示例,其中使用 "%F" 格式说明符和 std::format 很好地格式化一个 year_month_day 反对 std::cout 也。

考虑到功能的重要性,我们使用了一些工具来帮助维护人员和社区组织和跟踪需要完成的工作。添加到 <chrono> 标题通过功能的 GitHub问题 ,并通过 扩展到 GitHub项目和 跟踪问题 . 您可以阅读更多关于该特性所需的代码更改以及我们在那里实现时必须考虑的具体因素。

这是对 <chrono> 包含在C++ 20中,但是已经添加了比这里已经覆盖的页眉更多的内容。这些功能可供公众使用 /std:c++latest 从VisualStudio2019版本10预览版3、4和GA开始,我鼓励您使用它们来实现所有最疯狂的日历、时区和闰秒相关梦想,并让我们知道您的想法!

© 版权声明
THE END
喜欢就支持一下吧,技术咨询可以联系QQ407933975
点赞0 分享