Почему глобальная временная зона glibc не соответствует системному времени по летнему времени? - PullRequest
6 голосов
/ 11 марта 2009

У меня странная проблема, когда мои системные часы знают, что это летнее время, а glibc - нет. Это современная установка Ubuntu, и я проверил / etc / localtime, и она имеет правильное время переключения для перехода на DST на прошлой неделе.

Текущий правильный часовой пояс для меня - Тихоокеанское летнее время (UTC-7). Когда я спрашиваю мою систему, в каком часовом поясе я нахожусь, она правильно говорит:

$ date +%z
-0700

Но когда я запускаю следующую программу:

#include <time.h>
#include <stdio.h>

int main() {
  tzset();
  printf("%lu\n", timezone);
  return 0;
}

Вывод неверный:

28800

Что соответствует UTC-8 или тихоокеанскому стандартному времени. (И нет, TZ не установлен в моей среде)

Я думал, что glibc и программа date получат информацию о часовом поясе из одного и того же источника, но, очевидно, либо нет, либо я неправильно понимаю, как работает глобальный часовой пояс glibc.

Основные вопросы:

  1. Почему эти два выхода отличаются
  2. Как надежно определить смещение UTC системы из программы на C?

Ответы [ 4 ]

3 голосов
/ 11 марта 2009

Я не думаю, что "часовой пояс" меняется с переходом на летнее время. Попробуйте переменную дневного света. В моей системе:

      The external variable timezone contains the difference, in seconds,
      between UTC and local standard time (for example, in the U.S. Eastern
      time zone (EST), timezone is 5*60*60).  The external variable daylight
      is non-zero only if a summer time zone adjustment is specified in the
      TZ environment variable.
1 голос
/ 08 января 2011

Посмотрите на поле tm.tm_isdst после этого:

  time_t current_time;
  struct tm tm;

  current_time = time(NULL);
  localtime_r(&current_time, &tm);

Согласно man-странице localtime_r (3), это фактически указывает, действует ли DST в указанное время. Я думаю, что вам нужно предположить, что DST добавляет один час к переменной timezone (3), которую вы уже используете, или выполните различие против GMT.

Работает для меня в австралийском AEST, надеюсь, это работает для вас.

0 голосов
/ 29 апреля 2015

Вот мой код для этого, используя tm_gmtoff, если определено linux , и используя timezone.tz_minuteswest из gettimofday в противном случае (здесь 'ltm' - это вывод localtime):

{
    int tz_offset;

#if defined(__linux__)
    tz_offset= ltm.tm_gmtoff;
#else
    tz_offset= -tz.tz_minuteswest*60 + ltm.tm_isdst*3600;
#endif

     printf ("LT = UTC +d sec\n", tz_offset);
}
0 голосов
/ 18 марта 2011

Вы можете использовать tm_gmtoff член структуры tm, который совпадает с :: timezone, но учитывает DST и знак меняется на противоположный.

http://www.gnu.org/s/libc/manual/html_node/Time-Zone-Functions.html#Time-Zone-Functions

...