Linux上的时区转换C API,有人吗?

igo*_*gor 27 c linux timezone

我正在寻找一些我认为非常简单的东西 - 考虑到特定时区的本地Unix时间(指定为字符串,例如"America/New_York" - 请注意,这不是我当地的时间),得到相应的时间值在GMT.也就是说,有些东西

time_t get_gmt_time(time_t local_time,
                    const char* time_zone);
Run Code Online (Sandbox Code Playgroud)

听起来很简单,我能找到的最接近的是来自timegm手册页的以下代码片段:

       #include <time.h>
       #include <stdlib.h>

       time_t
       my_timegm(struct tm *tm)
       {
           time_t ret;
           char *tz;

           tz = getenv("TZ");
           setenv("TZ", "", 1);
           tzset();
           ret = mktime(tm);
           if (tz)
               setenv("TZ", tz, 1);
           else
               unsetenv("TZ");
           tzset();
           return ret;
       } 
Run Code Online (Sandbox Code Playgroud)

有一种比这更好的方式不是线程安全的憎恶,对吧?对??

Fra*_*kH. 6

想在这里添加更多细节.

如果您尝试以下方法:

#include <stdio.h>
#include <time.h>    /* defines 'extern long timezone' */

int main(int argc, char **argv)
{
    time_t t, lt, gt;
    struct tm tm;

    t = time(NULL);
    lt = mktime(localtime(&t));
    gt = mktime(gmtime(&t));

    printf( "(t = time(NULL)) == %x,\n"
        "mktime(localtime(&t)) == %x,\n"
        "mktime(gmtime(&t)) == %x\n"
        "difftime(...) == %f\n"
        "timezone == %d\n", t, lt, gt,
        difftime(gt, lt), timezone);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

您会注意到时区转换可确保:

  • mktime(localtime(t)) == t,和
  • mktime(gmtime(t)) == t + timezone,
    因此:
  • difftime(mktime(gmtime(t)), mktime(localtime(t))) == timezone
    (后者是由tzset()任何时区转换函数调用或初始化的全局变量).

以上示例输出:

$ TZ=GMT ./xx
(t = time(NULL)) == 4dd13bac,
mktime(localtime(&t)) == 4dd13bac,
mktime(gmtime(&t)) == 4dd13bac
difftime(...) == 0.000000
timezone == 0

$ TZ=EST ./xx
(t = time(NULL)) == 4dd13baf,
mktime(localtime(&t)) == 4dd13baf,
mktime(gmtime(&t)) == 4dd181ff
difftime(...) == 18000.000000
timezone == 18000

$ TZ=CET ./xx
(t = time(NULL)) == 4dd13bb2,
mktime(localtime(&t)) == 4dd13bb2,
mktime(gmtime(&t)) == 4dd12da2
difftime(...) == -3600.000000
timezone == -3600

从这个意义上讲,你试图"向后做" - 在UN*X中time_t被视为绝对,即始终相对于"EPOCH"(1970年1月1日0:00 UTC).

UTC与当前时区(最后一次tzset()通话)之间的差异始终在external long timezone全局范围内.

这并没有摆脱环境操纵丑陋,但你可以省去自己的努力mktime().


Cas*_*bel 1

我还真以为glib里有什么东西,不过好像记错了。我知道您可能正在寻找直接的 C 代码,但这是我拥有的最好的代码:

我知道 Python 通过一个类有一些时区的概念- 您可以在datetime 文档tzinfo中阅读它。您可以查看该模块的源代码(在 tarball 中位于 Modules/datetime.c 中) - 它似乎有一些文档,所以也许您可以从中得到一些东西。