为什么libc中的gmtime没有反函数?

时间:2016-07-11 02:15:13

标签: time posix libc

在libc中,有两个函数可以从系统时间转换为日历时间 - gmtimelocaltime,但只有localtime具有反函数 - mktime。为什么gmtime没有反函数,如果不存在,为什么gmtime存在?

2 个答案:

答案 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:00localtime()),因为 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);