虽然头文件自C++11以来已作为STL的一部分可用,但在C++20中包含的更改中,还有一些对chrono的扩展,包括对日历类型、时区、闰秒的支持以及格式。为了完成这些附加功能,需要进行大量的创新和工作;如果没有开源社区的大力支持,就不可能如此快地发布这些新的C++20新增功能。我要特别感谢MattStephanson、statementreply和DanielMarshall在帮助完成我们的实施方面做出的重要贡献。
概述和例子
在C++20的更改中,对头文件进行了大量添加,在这里我想强调一些。
日历类型
PRGH-:部分实现PR7,由DanielMarshall编写,在头文件中添加了一长串新的日历类型以支持日期。例如:
在这里,我们为年创建了一个year对象,然后使用它来创建一个表示年5月20日或世界蜜蜂日的year_month_day对象。然后,我们使用另一种形式来表示完全相同的一天,方法是创建一个month_weekday对象来表示未指定年份的5月的第三个星期四(用Thurs[3]表示,它正在创建一个weekday_indexed对象),然后使用它来创建一个year_month_weekday对象通过将它与被解释为年份的整数相结合。
你可以看到,该库现在包括各种不同的日历类型,允许用户以各种不同的方式创建日期。这些不同形式的日期旨在非常易于使用和直观,以便用户可以选择最舒适或最自然的方法。
时区
时区是头文件的另一个重要补充,其中包括新类型(例如time_zone、tzdb、zoned_time)以及对如何管理库新发现的时区所需的数据类型。下面是一个显示新时区功能示例的小示例:
这只是新添加的时区支持中包含的功能的一个小例子。该功能还支持不同时区之间的转换、“本地”时间的概念以及由于夏令时转换而导致的时区转换不明确或不存在的可能性。
在这个例子中,我们首先获得对包含时区数据的最新tzdb对象的引用。然后,我们使用它按名称查找美国/洛杉矶时区(GMT-07:00),在tzdb中存储指向该条目的time_zone指针。接下来,我们使用local_days和上面提到的一些日历类型创建一个特定的日期(对应于WorldNutellaDay),然后我们可以使用它来创建一个zoned_time对象,该对象与特定的日期/时间配对(在这种情况下,WorldNutellaDayat03:44:12)具有给定的时区(在本例中为美国/洛杉矶)。然后我们使用America/LosAngeleszoned_time创建一个与UTC时间相对应的zoned_time,说明时区转换功能。
我们在实现中遇到的一项具体挑战是如何实际访问时区所需的数据。C++20标准根据IANA数据库定义了时区功能,但是MSVC的STL由于其大小和如何为其提供更新的问题而无法随其实现一起提供整个数据库。我们不得不探索替代选项,因为我们思考如何支持这一标准规定的功能,而不会让我们的客户遭受的头文件大小的增加。我们最终发现了ICU库,它作为Windows10操作系统的一部分在更新的版本(19H1及之后)中提供,并从IANA数据库本身获取其数据。因此,对时区数据的更新将与通过Windows更新对操作系统的更新一起执行。虽然我们当前的实现依赖于更新的操作系统版本中ICUDLL的可用性,但我们计划重新审视这个问题并调查为旧操作系统实现回退。虽然IANA数据库和ICU库之间存在一些差异,但数据应该基本相同。
闰秒
我们最近的更改还包括对跟踪闰秒的支持,主要在MattStephanson的GH-:C++20时钟、clock_cast、tzdb::leap_seconds中实现,其中包含来自statementreply的宝贵意见。有了这个新支持,你可以询问给定时间是否发生在闰秒插入或删除期间(有趣的是,正闰秒和负闰秒都可能发生!)。C++20还添加了几种新的时钟类型(除了自C++11以来就存在的system_clock、steady_clock和high_resolution_clock),其中一些是闰秒感知的(例如utc_clock),而其他的则不是(例如system_clock)。我们通过Windows注册表检测新的闰秒(在DanCuomo的网络博客文章的指导下),因此任何新的闰秒也需要通过Windows更新来检测。
Chronat
chrono和std::format的交集,在我们的repo中被亲切地称为“chronat”,将C++20的两个最大特性结合在一起。“Chronat”包括对chrono新类型的解析和格式化,格式说明符/解析标志在很大程度上类似于strftime的格式化代码。在格式化方面,几乎所有添加到chrono的新类型都有结构格式化程序专门化,允许它与std::format的接口无缝集成。有关std::format的更多信息,请参阅CharlieBarto的博文。chrono解析和格式化的简短示例如下:
我们首先有一个实例,其中我们将stringstream解析为一天,然后可以将其输出到std::cout,然后我们还看到了一个实例,其中我们使用了“%F”格式说明符和std::format并很好地格式化了year_month_day对象到std::cout。
公开实现
鉴于该功能的重要性,我们使用了多种工具来帮助维护人员和社区组织和跟踪需要完成的工作。对头文件的添加是通过该功能的吉特哈布问题进行跟踪的,并且工作是通过吉特哈布项目的扩展和跟踪问题来组织的。你可以阅读更多关于该功能所需的代码更改以及我们在实现过程中必须考虑的特定注意事项。
总结
这是对包含在C++20中的扩展的适度简要概述,但添加到标题中的内容比此处介绍的要多得多。自VisualStudio版本10预览版3、4和GA起,这些功能在/std:c++latest下可供公众使用。我鼓励你使用它们来实现你所有最疯狂的日历、时区和闰秒相关的梦想,让我们知道你的想法!
最后
MicrosoftVisualC++团队的博客是我非常喜欢的博客之一,里面有很多关于VisualC++的知识和最新开发进展。大浪淘沙,如果你对VisualC++这门古老的技术还是那么感兴趣,则可以经常去他们那(或者我这)逛逛。本文来自:《C++20’sExtensionstoChronoAvailableinVisualStudioversion16.10》
最近我写了个东西
正如你们所知道的,拓扑梅尔智慧办公平台(TopomelBox)是一款绿色软件,主要面向经常使用电脑的朋友。它提供了各种提升办公效率的小功能,同时操作上尽可能地简单方便。我想:你值得拥有。