在C中操纵时间(在时区之间)的一般方法?

在为时区之间的转换问题编写示例代码之后,其中一条评论是需要更通用的方法从时区A转换到时区B.我自己也很好奇为这样一个更高级别的原语一个操纵,所以我写了下面的代码。

我看到的一个缺点是它不断地在环境变量中摆动TZ,改变了“本地时间”的概念。 虽然它似乎有效(虽然我没有检查它对DST时期的反应,但因为它基于Olson数据库,大概应该是这样),我很好奇是否有人可能有更好的想法如何处理这个任务?

#include  #include  #include  #include  time_t utc_now() { struct timeval tv_utc; gettimeofday(&tv_utc, NULL); return tv_utc.tv_sec; } void use_tz(char *timezone) { if(timezone) { setenv("TZ", timezone, 1); } else { unsetenv("TZ"); } tzset(); } time_t utc_from_local_tm(struct tm *local_tm, char *timezone) { time_t utc; use_tz(timezone); utc = mktime(local_tm); return utc; } struct tm *local_tm_from_utc(time_t utc, char *timezone) { use_tz(timezone); return localtime(&utc); } int main(int argc, char *argv[]) { struct tm *tm; struct tm tm2; time_t utc, utc2, utc3; utc = utc_now(); tm = local_tm_from_utc(utc, "Europe/Brussels"); printf("Local time in Brussels now: %s", asctime(tm)); utc2 = utc_from_local_tm(tm, "Europe/Moscow"); tm = local_tm_from_utc(utc2, "UTC"); printf("UTC time if the above was the Moscow local time: %s", asctime(tm)); memset(&tm2, sizeof(tm2), 0); /* 13:00:00 on 11 dec 2010 */ tm2.tm_sec = tm2.tm_min = 0; tm2.tm_hour = 13; tm2.tm_mon = 11; tm2.tm_mday = 11; tm2.tm_year = 110; utc3 = utc_from_local_tm(&tm2, "Europe/Brussels"); printf("Brussels time: %s", asctime(&tm2)); tm = local_tm_from_utc(utc3, "Europe/Moscow"); printf("At 13:00:00 on 11 dec 2010 CET the time in Moscow will be: %s", asctime(tm)); exit(0); } 

如果将TZ信息存储在环境变量中,那么如何创建一个包含struct tm以及TZ信息的char *的新结构?

我被宠坏了,因为R做得很好:

 R> now <- Sys.time() R> now [1] "2009-08-01 17:19:07 CDT" R> format(now, tz="Europe/Brussels") [1] "2009-08-02 00:19:07" R> 

它对标准POSIX函数有一些扩展/替换,参见文件R-2.9.1 / src / main / datetime.c(其中R-2.9.1是当前版本)