以下是使用Howard Hinnant's date library 的方法。这是一个免费的 MIT 许可的 C++11/14 库,基于 <chrono>:
#include "tz.h"
#include <iostream>
int
main()
{
using namespace std::chrono_literals;
using namespace date;
auto unix_timestamp = sys_seconds{1479664467s};
auto zt = make_zoned("America/Los_Angeles", unix_timestamp);
auto wd = weekday{floor<days>(zt.get_local_time())};
std::cout << wd << '\n';
}
第一行只是构造 unix 时间戳(您可能从其他来源获得)。在 C++11 中,我们没有 chrono-literals,因此这一行将改为:
auto unix_timestamp = sys_seconds{seconds{1479664467}};
make_zoned() 基于unix_timestamp 和time_zone "America/Los_Angeles" 创建一个zoned_time<seconds>。 zoned_time 是 time_zone 和 unix 时间戳的集合。
您可以使用zt.get_local_time() 从zoned_time 中获取当地时间。这是一个chrono::time_point,但没有与之关联的时钟。此时间点的精度将等于您原始时间戳的精度(在本例中为秒)。
您可以通过将local_time 截断为days 的精度来获得local_time 的星期几:
floor<days>(zt.get_local_time())
而这一天精度 time_point 将转换为类型 weekday。
可以打印出weekday,参与weekday 算术和比较,或者在[0, 6] 范围内显式转换为unsigned。
上面的程序输出:
Sun
这个库的时区部分是IANA timezone database 的忠实代表。从 1800 年代中期到现在,它将在本地时区和 UTC 之间进行正确调整。如果您在 1800 年中期之前传递库时间戳,则已知最早的 UTC 偏移量将向后推算到 -32768 年。您还可以将时间戳传递到 32767 年,当前的偏移量和夏令时规则将向前传播。
由于这个库是基于<chrono> 构建的,它可以处理<chrono> 提供的任何精度。请注意,某些chrono::durations,例如nanoseconds 的范围更有限(nanoseconds 为+/-292 年)。
库/进程是线程安全的。也就是说,该程序直接与您指定的任何时区一起工作,而无需在后台更改计算机的时区或环境变量。它也不涉及 C 计时 API 的部分,由于非 const 函数局部静态,该部分已知不是线程安全的。
移植到最新版本的 gcc、clang 和 VS。
更新 C++20
上面的程序可以很容易地移植到 C++20(我写的时候有些供应商支持这个,有些还不支持):
#include <chrono>
#include <iostream>
int
main()
{
using namespace std::chrono;
auto unix_timestamp = sys_seconds{1479664467s};
auto zt = zoned_time{"America/Los_Angeles", unix_timestamp};
auto wd = weekday{floor<days>(zt.get_local_time())};
std::cout << wd << '\n';
}