有趣的问题(已投票)。一般来说,这个答案不能一概而论。而“CDT”/now 就是一个很好的例子来证明这一点。 sehe's answer 使用 boost/datetime 做得很好。此答案使用此free, open source timezone library 提供了更多详细信息。
这是代码,然后是解释,然后是输出,然后是与sehe's answer 的比较。
#include "tz.h"
#include <string>
#include <iostream>
#include <vector>
template <class Duration>
std::vector<date::time_zone const*>
find_by_abbrev(date::sys_time<Duration> tp, const std::string& abbrev)
{
using namespace std::chrono;
using namespace date;
std::vector<time_zone const*> results;
auto& db = get_tzdb();
for (auto& z : db.zones)
{
if (z.get_info(tp).abbrev == abbrev)
results.push_back(&z);
}
return results;
}
int
main()
{
using namespace std::chrono;
using namespace date;
auto now = sys_days{2016_y/4/1} + 10h + 15min + 2s;
auto v = find_by_abbrev(now, "CDT");
for (auto zp : v)
std::cout << make_zoned(zp, now) << " " << zp->name() << '\n';
}
策略是列出当前使用“CDT”作为缩写的所有时区。为此,创建了一个函数,该函数接受std::chrono::time_point<std::chrono::system_clock, Duration> 和一个缩写并返回一个vector<time_zone const*>。一旦找到,就可以简单地迭代这个vector,并打印出每个时区的信息。
要实现find_by_abbrev,则必须搜索整个时区数据库。每个在 tp 时使用缩写 abbrev 的 time_zone 都会添加到列表中。
为了使这些结果易于与sehe's answer 进行比较,我在程序中使用了相同的时间(而不是当前时间)。
程序输出:
2016-04-01 05:15:02 CDT America/Chicago
2016-04-01 06:15:02 CDT America/Havana
2016-04-01 05:15:02 CDT America/Indiana/Knox
2016-04-01 05:15:02 CDT America/Indiana/Tell_City
2016-04-01 05:15:02 CDT America/Matamoros
2016-04-01 05:15:02 CDT America/Menominee
2016-04-01 05:15:02 CDT America/North_Dakota/Beulah
2016-04-01 05:15:02 CDT America/North_Dakota/Center
2016-04-01 05:15:02 CDT America/North_Dakota/New_Salem
2016-04-01 05:15:02 CDT America/Rainy_River
2016-04-01 05:15:02 CDT America/Rankin_Inlet
2016-04-01 05:15:02 CDT America/Resolute
2016-04-01 05:15:02 CDT America/Winnipeg
2016-04-01 05:15:02 CDT CST6CDT
现在我发现特别有趣的是将此输出与基于 boost/datetime 的sehe's answer 进行比较:
此答案省略了“America/Cancun”,因为它当前未使用缩写 CDT,并且自 2014 年 10 月 26 日 07:00:00 UTC 以来未使用。
两个答案都将“美国/哈瓦那”显示为潜在的 CDT 时区,但只有此答案显示“美国/哈瓦那”单独的 UTC 偏移量比所有其他候选时区少一小时。
其他差异仍在继续,但解释类似。
此库允许您控制您想要更新IANA database 的时间/频率,如果您的系统安装了libcurl,甚至可以自动下载最新的IANA database。
使用这个库,我已经证明“CDT/now”不仅在应选择的 IANA 时区方面模棱两可,而且对于所选时区的当前 UTC 偏移量也模棱两可。通常要解决这样的问题,需要更多的先验知识,例如“我知道时间戳是指与美国相关的时间戳”(或其他)。
但是一旦你决定了一个区域(通过任何启发式方法):
auto zone = locate_zone(chosen_zone);
auto local = zone->to_local(system_clock::now());
你已经明白了。
免责声明:需要 C++11 或更高版本。这是一个相当现代的图书馆。没有<chrono> 支持就无法移植。