AlexRayne 7 8 августа, 2022 Опубликовано 8 августа, 2022 · Жалоба пытаюсь cконвертировать локальное время tm_t -> в UTC time_t. Но результат функций mktime и localtime_r делает поправку на часовой пояс непонятным образом: 1) установлен часовой пояс по москве - 3часа, так что timezone = 3*3600= 10800 2) вызываю time_t utc_now = mktime( local_now /* tm_t */ ) ; tm_t utc_tm; gmtime( utc_now, utc_tm); после этого комбо utc_tm содержит время local_now + 3часа. Но кактакта, ведь локальное время = UTC+timezone ? а значит utc_tm должно быть меньше на timezone чем локальное. Полез исходники newlibc. И действительно там так оно и вычисляется: - mktime прибавляет к результату timezone. тое: UTC = localtm + timezone - localtime_r вычитает из результат timezone. тое: localtm = UTC - timezone (вот это прямо совсем против определения часового пояса) - tzset устанавливает смещение timezone именно с тем знаком , который в строке установки TZ указан. Что я делаю не так? Кто знает, кто опытный? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
k155la3 26 9 августа, 2022 Опубликовано 9 августа, 2022 · Жалоба да, нечто такое было. IAR/MSP430 xtime.h Пришлось немного откорректировать (//) ф-ю mktime из-за того, что я не нашел, как установить часы, которые "шли" по UTC, из структуры tm "напрямую" без учета таймзоны/DST. time_t mktimeDir32(struct tm *t) { /* convert local time structure to scalar time */ long cdays, csecs; int mon, year, ymon; __time32_t secs; ymon = t->tm_mon / 12; mon = t->tm_mon - ymon * 12; if (mon < 0) mon += 12, --ymon; if (ymon < 0 && t->tm_year < INT_MIN - ymon || 0 < ymon && INT_MAX - ymon < t->tm_year) return ((__time32_t)(-1)); year = t->tm_year + ymon; /* Note that this is correct even with a 32 bit double. */ /* Calculate number of days. */ cdays = __iar_Daysto32(year, mon) - 1; cdays += 365L * year; cdays += t->tm_mday; /* Calculate number of seconds. */ cdays += t->tm_hour / 24; csecs = 3600L * (t->tm_hour % 24); cdays += t->tm_min / (24 * 60); csecs += 60L * (t->tm_min % (24 * 60)); cdays += t->tm_sec / 86400L; csecs += t->tm_sec % 86400L; /* Change from 1900 into 1970 representation. */ cdays -= _TBIAS_DAYS; /* Add them together to get seconds since 1970. */ secs = cdays * 86400L + csecs; __iar_Ttotm32(t, secs, t->tm_isdst); // if (0 < t->tm_isdst) secs -= 3600; // коррекция DST // return (secs - _Tzoff()); // коррекция смещения TZ return(secs); } (К сведению), материалы см. wiki "tz database" итд Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AlexRayne 7 9 августа, 2022 Опубликовано 9 августа, 2022 · Жалоба Закрываю тему. Всем спасибо! Я невнимательно читал документацию на timezone: Цитата This contains the difference between UTC and the latest local standard time, in seconds west of UTC. For example, in the U.S. Eastern time zone, the value is 5*60*60. ... and its sign is reversed. вот оказывается не учел что её знак реверснут Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться