Общий способ манипулировать временем (между часовыми поясами) в C? - PullRequest
4 голосов
/ 02 августа 2009

После написания примера кода для вопроса о преобразовании между часовыми поясами , одним из комментариев к нему стала необходимость в более общем методе преобразования из часового пояса A в часовой пояс B. Мне тоже было любопытно У меня есть более высокоуровневые примитивы для таких манипуляций, поэтому я написал следующий код.

Один недостаток, который я вижу, заключается в том, что он постоянно покачивает TZ в переменных среды, изменяя понятие «местного времени». Хотя это, кажется, работает (хотя я не проверял, как оно реагирует на периоды летнего времени, но поскольку оно основано на базе данных Olson, предположительно, так и должно быть), мне было любопытно, есть ли у кого-нибудь лучшие идеи о том, как справиться с этим задача?

#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 Ответ

1 голос
/ 02 августа 2009

Если хранение информации о TZ в переменной среды вызывает ошибки, то как насчет создания новой структуры, которая содержит как struct tm, так и char * для информации TZ?

Я избалован, потому что 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 - текущая версия)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...