在libc中,有两个函数可以从系统时间转换为日历时间 - gmtime
和localtime
,但只有localtime
具有反函数 - mktime
。为什么gmtime
没有反函数,如果不存在,为什么gmtime
存在?
答案 0 :(得分:1)
要解释gmtime()
的存在,需要一些上下文:
gmtime()
会将时间戳表示(自1970-01-01 00:00:00
以来的秒数)转换为细分时间表示(aka,{{1假设时间戳时区 UTC :
struct tm
功能将日历时间timep转换为 细分时间表示,以 Coordinated Universal表示 时间(UTC)。当年份不适合时,它可能返回NULL 整数。返回值指向静态分配的结构 可能会被后续调用任何日期覆盖 和时间功能。
另一方面,gmtime()
考虑了[本地]系统时区(包括夏令时):
localtime()
功能将日历时间timep转换为 分解时间表示,相对于用户表示 指定的时区。该函数就像调用localtime()
和。{ 设置外部变量tzname以及有关的信息 当前时区,时区与Coordinated之间的差异 世界时(UTC)和本地标准时间(秒),和 如果夏令时规则适用,则日光为非零值 在一年中的某些时候。
请注意,tzset(3)
以后的秒数与时区不同(纽约时为1970-01-01 00:00:00
,显然不在东京)。
1970-01-01 00:00:00
根据[local]系统时区将mktime()
转换为struct tm
值(自time_t
以来的秒数),应< / em>不被解释为任何特定函数的逆(例如1970-01-01 00:00:00
或localtime()
),因为 inverse 术语可能是[错误地]被解释为安全的跨系统转换:
gmtime()
函数转换细分时间结构, 以当地时间表示,以日历时间表示。该 function忽略tm_wday中调用者提供的值 和tm_yday字段。 tm_isdst字段中指定的值通知 mktime()是否夏令时(DST)生效 对于tm结构中提供的时间:正值表示DST 已生效;
还有一个名为mktime()
的非可移植函数(用于GNU和BSD系统),它假定为UTC时区,例如timegm()
。
<强>参考强>
从Linux手册页项目的3.74版本的部分中检索了块引用的文本。
答案 1 :(得分:1)
我发现这段代码令人满意:
namespace std {
time_t timegm(tm* _Tm)
{
auto t = mktime(_Tm);
return t + (mktime(localtime(&t)) - mktime(gmtime(&t)));
}
}
满足了测试:
auto t1 = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
auto t2 = std::timegm(std::gmtime(&t1));
EXPECT_EQ(t1, t2);