代码之家  ›  专栏  ›  技术社区  ›  Andrew Y

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

  •  4
  • Andrew Y  · 技术社区  · 15 年前

    在为关于 converting between timezones 其中一条评论是需要更通用的方法来从时区A转换到时区B。我也很好奇自己是否有更高级的原语来进行这样的操作,所以我写了下面的代码。

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

    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    #include <sys/time.h>
    
    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);
    }
    
    1 回复  |  直到 15 年前
        1
  •  1
  •   Dirk is no longer here    15 年前

    如果将TZ信息存储在一个环境变量中会使您出错,那么如何创建一个既包含struct tm又包含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是当前版本)。