一个老问题的新答案。
新答案的基本原理:现在有一个
modern, free, open-source, C++11/14/17 library
1
它确实需要
一些
installation
full documentation
,甚至是
video introduction
.
下面是一个获取特定时区信息的示例程序。我只是以我自己的时区为例。此库支持完整的
IANA timezone database
:
#include "tz.h"
#include <iostream>
int
main()
{
auto zone = date::locate_zone("America/New_York");
std::cout << *zone << '\n';
std::cout << zone->get_info(std::chrono::system_clock::now()) << '\n';
}
第一行按其IANA名称查找数据库。
auto zone = date::locate_zone("America/New_York");
date::time_zone const*
nullptr
,但如果找不到时区,它将抛出(具有极好的
what()
).
std::cout << *zone << '\n';
这一行的输出通常对这个库的客户机没有用处。在调试库时,它主要对我自己有用:
America/New_York -04:56:02 LMT 1883 Nov/18 12:03:58 1883-11-18 17:00:00 UTC 1883-11-18 12:03:58 STD 1883-11-18 12:03:58 00:00 {nullptr, -32768} {nullptr, 32767}
-05:00:00 US E%sT 1920 Jan/01 00:00:00 1920-01-01 05:00:00 UTC 1920-01-01 00:00:00 STD 1920-01-01 00:00:00 00:00 S {US 1918 1919 Mar/Sun[last] 02:00:00 01:00 D, 1918} {US 1918 1919 Oct/Sun[last] 02:00:00 00:00 S, 1919}
-05:00:00 NYC E%sT 1942 Jan/01 00:00:00 1942-01-01 05:00:00 UTC 1942-01-01 00:00:00 STD 1942-01-01 00:00:00 00:00 S {NYC 1920 1920 Mar/28 02:00:00 01:00 D, 1920} {NYC 1921 1954 Sep/Sun[last] 02:00:00 00:00 S, 1941}
-05:00:00 US E%sT 1946 Jan/01 00:00:00 1946-01-01 05:00:00 UTC 1946-01-01 00:00:00 STD 1946-01-01 00:00:00 00:00 S {US 1942 1942 Feb/09 02:00:00 01:00 W, 1942} {US 1945 1945 Sep/30 02:00:00 00:00 S, 1945}
-05:00:00 NYC E%sT 1967 Jan/01 00:00:00 1967-01-01 05:00:00 UTC 1967-01-01 00:00:00 STD 1967-01-01 00:00:00 00:00 S {NYC 1921 1954 Apr/Sun[last] 02:00:00 01:00 D, 1946} {NYC 1955 1966 Oct/Sun[last] 02:00:00 00:00 S, 1966}
-05:00:00 US E%sT 32767 Dec/31 00:00:00UTC 32767-12-31 00:00:00 UTC 32767-12-30 19:00:00 STD 32767-12-30 19:00:00 00:00 S {US 1967 1973 Apr/Sun[last] 02:00:00 01:00 D, 1967} {US 2007 32767 Nov/Sun[1] 02:00:00 00:00 S, 32767}
但我展示这一行的原因之一是为了说明询问时区信息,而不同时提供
,不太可能提供您要查找的信息。关于时区的信息本身就是时间的函数,包括偏移量、夏令时细节、缩写等。
最后一行:
std::cout << zone->get_info(std::chrono::system_clock::now()) << '\n';
可能是最有用的。这将返回一个聚合
sys_info
看起来是这样的:
struct sys_info
{
sys_seconds begin;
sys_seconds end;
std::chrono::seconds offset;
std::chrono::minutes save;
std::string abbrev;
};
2016-11-06 06:00:00
2017-03-12 07:00:00
-05:00:00
00:00
EST
-
此信息的有效期为2016-11-06 06:00:00 UTC至(但不包括)2017-03-12 07:00:00 UTC。
-
-
这不被视为夏令时(save==00:00)。
-
这个时期的缩写是EST。
当然,您可以在程序中访问这个聚合的字段,而不是仅仅打印出来。
如果您想查看6个月后的结果:
std::cout << zone->get_info(std::chrono::system_clock::now() + date::months{6}) << '\n';
2017-03-12 07:00:00
2017-11-05 06:00:00
-04:00:00
01:00
EDT
所有这些都被认为是该库的低级访问。存在更高级别的API,因此您不必处理低级别的概念,例如当前的UTC偏移量。如果您需要的话,底层的东西就在那里(不是隐藏的),但是对于常见的用例(比如获取任何特定时区的当前时间)来说不是必需的:
using namespace date;
using namespace std::chrono;
std::cout << make_zoned("America/New_York", system_clock::now()) << '\n';
对我来说:
2017-03-07 19:26:53.711662 EST
在C++ 17中,由于模板推导指南,上述行不再需要“制造工厂函数”用于演绎目的:
std::cout << zoned_time{"America/New_York", system_clock::now()} << '\n';
zoned_time
是一个类模板,以持续时间为模板,由
chrono::duration
的
chrono::time_point
(第二个论点——在我的例子中)
microseconds
).
这是一个具有低级别访问和高层次抽象的完整功能的日期/时间/时区库(对C++的哲学是正确的)。正确性和类型安全性在这个库中受到高度重视。它是一个
<chrono>
在C++ 11中引入了库。
1
免责声明:我是这个图书馆的主要作者,尽管有很多贡献者(对此我很感激)。