C+20的Chrono擴充套件正式可用

雖然 標頭檔案自C++ 11以來已作為STL的一部分可用,但在C++ 20中包含的更改中,還有一些對chrono的擴充套件,包括對日曆型別、時區、閏秒的支援以及格式。 為了完成這些附加功能,需要進行大量的創新和工作;如果沒有開源社群的大力支援,就不可能如此快地釋出這些新的C++ 20新增功能。 我要特別感謝 Matt Stephanson、statementreply 和 Daniel Marshall 在幫助完成我們的實施方面做出的重要貢獻。

概述和例子

在C++ 20的更改中,對標頭檔案進行了大量新增,在這裡我想強調一些。

日曆型別

PR GH-323: 部分實現 P0355R7,由 Daniel Marshall 編寫,在標頭檔案中添加了一長串新的日曆型別以支援日期。 例如:

C+20的Chrono擴充套件正式可用

在這裡,我們為 2021 年建立了一個 year 物件,然後使用它來建立一個表示 2021 年 5 月 20 日或世界蜜蜂日的 year_month_day 物件。 然後,我們使用另一種形式來表示完全相同的一天,方法是建立一個 month_weekday 物件來表示未指定年份的 5 月的第三個星期四(用 Thurs[3] 表示,它正在建立一個 weekday_indexed 物件),然後使用它來建立一個 year_month_weekday 物件透過將它與被解釋為年份的整數 2021 相結合。

你可以看到,該庫現在包括各種不同的日曆型別,允許使用者以各種不同的方式建立日期。 這些不同形式的日期旨在非常易於使用和直觀,以便使用者可以選擇最舒適或最自然的方法。

時區

時區是 標頭檔案的另一個重要補充,其中包括新型別(例如 time_zone、tzdb、zoned_time)以及對如何管理庫新發現的時區所需的資料型別。 下面是一個顯示新時區功能示例的小示例:

C+20的Chrono擴充套件正式可用

這只是新新增的時區支援中包含的功能的一個小例子。該功能還支援不同時區之間的轉換、“本地”時間的概念以及由於夏令時轉換而導致的時區轉換不明確或不存在的可能性。

在這個例子中,我們首先獲得對包含時區資料的最新 tzdb 物件的引用。

然後,我們使用它名稱查詢美國/洛杉磯時區 (GMT-07:00),在 tzdb 中儲存指向該條目的 time_zone 指標。

接下來,我們使用 local_days 和上面提到的一些日曆型別建立一個特定的日期(對應於 World Nutella Day),然後我們可以使用它來建立一個 zoned_time 物件,該物件與特定的日期/時間配對(在這種情況下,World Nutella Day at 03 :44:12) 具有給定的時區(在本例中為美國/洛杉磯)。

然後我們使用 America/Los Angeles zoned_time 建立一個與 UTC 時間相對應的 zoned_time,說明時區轉換功能。

我們在實現中遇到的一項具體挑戰是如何實際訪問時區所需的資料。

C++ 20標準根據 IANA 資料庫定義了時區功能,但是 MSVC 的 STL 由於其大小和如何為其提供更新的問題而無法隨其實現一起提供整個資料庫。

我們不得不探索替代選項,因為我們思考如何支援這一標準規定的功能,而不會讓我們的客戶遭受的標頭檔案大小的增加。

我們最終發現了 ICU 庫,它作為 Windows 10 作業系統的一部分在更新的版本(19H1 及之後)中提供,並從 IANA 資料庫本身獲取其資料。

因此,對時區資料的更新將與透過 Windows 更新對作業系統的更新一起執行。

雖然我們當前的實現依賴於更新的作業系統版本中 ICU DLL 的可用性,但我們計劃重新審視這個問題並調查為舊作業系統實現回退。

雖然 IANA 資料庫和 ICU 庫之間存在一些差異,但資料應該基本相同。

閏秒

我們最近的更改還包括對跟蹤閏秒的支援,主要是在 MattStephanson 的 GH-1671:C++20 時鐘、clock_cast、tzdb::leap_seconds 中實現,其中包含來自 statementreply 的寶貴意見。

有了這個新支援,你可以詢問給定時間是否發生在閏秒插入或刪除期間(有趣的是,正閏秒和負閏秒都可能發生!)。

C++20 還添加了幾種新的時鐘型別(除了自 C++11 以來就存在的 system_clock、steady_clock 和 high_resolution_clock),其中一些是閏秒感知的(例如 utc_clock),而其他的則不是(例如 system_clock)。

我們透過 Windows 登錄檔檢測新的閏秒(在 Dan Cuomo 的網路部落格文章的指導下),因此任何新的閏秒也需要透過 Windows 更新來檢測。

Chronat

chrono 和 std::format 的交集,在我們的 repo 中被親切地稱為“chronat”,將 C++ 20的兩個最大特性結合在一起。 “Chronat”包括對 chrono 新型別的解析和格式化,格式說明符/解析標誌在很大程度上類似於 strftime 的格式化程式碼。 在格式化方面,幾乎所有新增到 chrono 的新型別都有結構格式化程式專門化,允許它與 std::format 的介面無縫整合。 有關 std::format 更多資訊,請參閱 Charlie Barto 的博文。 chrono 解析和格式化的簡短示例如下:

C+20的Chrono擴充套件正式可用

我們首先有一個示例,其中我們將 stringstream 解析為一天,然後可以將其輸出到 std::cout,然後我們還看到了一個示例,其中我們使用了“%F”格式說明符和 std::format 並很好地格式化了 year_month_day 物件到 std::cout 。

公開實現

鑑於該功能的重要性,我們使用了多種工具來幫助維護人員和社群組織和跟蹤需要完成的工作。

對 標頭檔案的新增是透過該功能的 吉特哈布 問題進行跟蹤的,並且主要工作是透過 吉特哈布 專案的擴充套件和跟蹤問題來組織的。 你可以閱讀更多關於該功能所需的程式碼更改以及我們在實現過程中必須考慮的特定注意事項。

總結

這是對包含在 C++20 中的 擴充套件的適度簡要概述,但新增到標題中的內容比此處介紹的要多得多。 自 Visual Studio 2019 版本 10 預覽版 3、4 和 GA 起,這些功能在 /std:c++latest 下可供公眾使用。 我鼓勵你使用它們來實現你所有最瘋狂的日曆、時區和閏秒相關的夢想,讓我們知道你的想法!

最後

Microsoft Visual C++團隊的部落格是我非常喜歡的部落格之一,裡面有很多關於Visual C++的知識和最新的開發進展。大浪淘沙,如果你對Visual C++這門古老的技術還是那麼感興趣,則可以經常去他們那(或者我這)逛逛。

本文來自:《C++20’s Extensions to Chrono Available in Visual Studio 2019 version 16。10》

最近我寫了個東西

正如你們所知道的,拓撲梅爾智慧辦公平臺(Topomel Box)是一款綠色軟體,主要面向經常使用電腦的朋友。它提供了各種提升辦公效率的小功能,同時操作上儘可能地簡單方便。

我想:你值得擁有。

C+20的Chrono擴充套件正式可用

TAG: C++閏秒20時區我們