如何在C语言中通过编程将时间从一个时区转换为另一个时区?

如何在C语言中通过编程将时间从一个时区转换为另一个时区?,c,datetime,time,timezone,C,Datetime,Time,Timezone,GNUdate命令的信息页面包含以下示例: 例如,使用GNUdate 你能回答这个问题吗 “在纽约什么时候有人来 巴黎的时钟显示十月六日上午六点半 “使用以日期开始的日期” 如中所示,使用“TZ=”欧洲/巴黎“ 以下是壳牌公司的发言稿: $ export TZ="America/New_York" $ date --date='TZ="Europe/Paris" 2004-10-31 06:30' Sun Oct 31 01:30:00 EDT 2004 在本例中,“--date” 操作

GNU
date
命令的信息页面包含以下示例:

例如,使用GNU
date
你能回答这个问题吗 “在纽约什么时候有人来 巴黎的时钟显示十月六日上午六点半 “使用以日期开始的日期” 如中所示,使用“TZ=”欧洲/巴黎“ 以下是壳牌公司的发言稿:

 $ export TZ="America/New_York"
 $ date --date='TZ="Europe/Paris" 2004-10-31 06:30'
 Sun Oct 31 01:30:00 EDT 2004
在本例中,“--date” 操作数以其自身的“TZ”开头 设置,则该操作数的其余部分 是根据 “欧洲/巴黎”规则,处理 字符串
2004-10-3106:30
我们在巴黎。但是,
date
命令的输出为 按照整体流程进行处理 时区规则,它使用纽约 时间(巴黎通常是六小时 比2004年的纽约早,但是 这个例子指的是一个简短的万圣节 间隔为五小时的时间。)

我试图用C语言编程完成基本相同的事情,而不需要调用
date
程序数百万次。基本上,我正在寻找一种方法,在一个时区中获取任意日期和时间,并直接或通过转换到UTC或从UTC转换到UTC,将其转换为另一个时区中的等效日期和时间。我不关心输入和输出时间的格式,只要我可以使用标准函数操作它们(
strftime
/
strptime
/
mktime
/etc)

date
程序似乎是使用
coreutils
包内部的复杂例程来完成这项工作的,我正在寻找一种在C中使用标准POSIX/Linux例程或外部库来完成这项工作的方法。我看了很多看起来很有希望的东西,但我找不到任何库可以用它做任何有用的事情。

时间:

  • 使用
    gmtime
  • 从时间中加/减小时
  • 使用
    mktime
    重新规范化

日期计算将是类似的,但有点复杂。

我提出了一个解决方案,似乎可以在Linux上与glibc一起工作,我不知道这种行为的可移植性如何,欢迎对可移植性或更好的方法发表任何意见

convert_time.c(为清晰起见无错误检查):


我实际上在寻找与你相同的答案,这就是我提出的解决方案。 下面的示例程序获取本地系统时间并将其转换为所需的任何时区

// compile: gcc snippet.c
// usage: ./a.out Europe/Berlin Pacific/Nauru Asia/Hong_Kong Asia/Kabul
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <errno.h>

int main(int argc, char *argv[])
{
        char buf[80];
        time_t tt = time(NULL);
        struct tm tm;
        int i;

        if (!localtime_r(&tt, &tm)) {
                printf("Could not convert time_t to tm struct. %s\n", strerror(errno));
                return 1;
        }

        printf("time_t: %ld\n", tt);
        printf("timezone: %ld, %s/%s, daylight:%d\n", timezone, tzname[0], tzname[1],  daylight);
        strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S %z %Z", &tm);
        printf("time: %s\n", buf);

        for (i = 1; i < argc; ++i) {
                printf("\ninput: %s\n", argv[i]);

                snprintf(buf, sizeof(buf), "TZ=%s", argv[i]);
                putenv(buf);
                tzset();
                printf("\ttimezone: %ld, %s/%s, daylight:%d\n", timezone, tzname[0], tzname[1], daylight);

                if (!localtime_r(&tt, &tm)) {
                        printf("Could not convert time_t to tm struct. %s\n", strerror(errno));
                        return 1;
                }

                strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S %z %Z", &tm);
                printf("\ttime: %s\n", buf);
        }

        return 0;
}
//编译:gcc snippet.c
//用法:./a.out欧洲/柏林太平洋/瑙鲁亚洲/香港亚洲/喀布尔
#包括
#包括
#包括
#包括
#包括
int main(int argc,char*argv[])
{
char-buf[80];
时间=时间(空);
struct-tm;
int i;
如果(!localtime_r(&tt,&tm)){
printf(“无法将时间转换为tm结构。%s\n”,strerror(errno));
返回1;
}
printf(“时间:%ld\n”,tt);
printf(“时区:%ld,%s/%s,日光:%d\n”,时区,tzname[0],tzname[1],日光);
strftime(buf,sizeof(buf),%Y-%m-%d%H:%m:%S%z%z“,&tm);
printf(“时间:%s\n”,buf);
对于(i=1;i
手动计算涉及到许多微妙的问题,我试图避免这些问题,例如必须处理DST之类的问题。这些信息包含在zoneinfo数据库中,但目前为止,这些信息对我来说并不是很有用。例如,这项工作在委内瑞拉尤其糟糕——官方称之为UTC-4:30糟糕,但你能做些什么?这正是手册页所说的操作:。这是非常不安全的。
$ ./convert_time "TZ=America/New_York" "2005-05-31 06:30" "TZ=America/Indiana/Indianapolis"
Tue, 31 May 2005 05:30:00 -0500(EST)

$ ./convert_time "TZ=America/New_York" "2006-05-31 06:30" "TZ=America/Indiana/Indianapolis"
Wed, 31 May 2006 06:30:00 -0400(EDT)

$ ./convert_time "TZ=Europe/Paris" "2004-10-30 06:30" "TZ=America/New_York"
Sat, 30 Oct 2004 00:30:00 -0400(EDT)

$ ./convert_time "TZ=Europe/Paris" "2004-10-31 06:30" "TZ=America/New_York"
Sun, 31 Oct 2004 01:30:00 -0400(EDT)

$ ./convert_time "TZ=Europe/Paris" "2004-11-01 06:30" "TZ=America/New_York"
Mon, 01 Nov 2004 00:30:00 -0500(EST)
// compile: gcc snippet.c
// usage: ./a.out Europe/Berlin Pacific/Nauru Asia/Hong_Kong Asia/Kabul
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <errno.h>

int main(int argc, char *argv[])
{
        char buf[80];
        time_t tt = time(NULL);
        struct tm tm;
        int i;

        if (!localtime_r(&tt, &tm)) {
                printf("Could not convert time_t to tm struct. %s\n", strerror(errno));
                return 1;
        }

        printf("time_t: %ld\n", tt);
        printf("timezone: %ld, %s/%s, daylight:%d\n", timezone, tzname[0], tzname[1],  daylight);
        strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S %z %Z", &tm);
        printf("time: %s\n", buf);

        for (i = 1; i < argc; ++i) {
                printf("\ninput: %s\n", argv[i]);

                snprintf(buf, sizeof(buf), "TZ=%s", argv[i]);
                putenv(buf);
                tzset();
                printf("\ttimezone: %ld, %s/%s, daylight:%d\n", timezone, tzname[0], tzname[1], daylight);

                if (!localtime_r(&tt, &tm)) {
                        printf("Could not convert time_t to tm struct. %s\n", strerror(errno));
                        return 1;
                }

                strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S %z %Z", &tm);
                printf("\ttime: %s\n", buf);
        }

        return 0;
}