Вопрос по c, timezone, glibc –  в стандарте

6

я странная проблема, когда мои системные часы знают, что это летнее время, а 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.

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

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

Ваш Ответ

4   ответа
3

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

      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.
Мое чтение справочной страницы для tzset указывает на то, что переменная дневного света только указывает, использует ли локальная зона летнее время в какой-то момент, и не обязательно указывает, действует ли она в настоящее время. Tyler McHenry
Я думаю, что я согласен с вами. Я бы предложил {time_t t = time (NULL); Е ( "% d \ п", (INT) difftime (указываете ей (gmtime (& т)), т)); } но это дает мне тот же результат, что и «часовой пояс». Randy Proctor
1

Посмотрите на поле 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

Вот мой код для этого, используя tm_gmtoff, еслилинукс определяется, и с помощью 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);
}
-1

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

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

Здесь нетtm_gmtoff в стандартеstruct tm. Some programmer dude

Похожие вопросы