Перейти к содержанию
    

как работает timezone в newlibc?

пытаюсь 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 указан.

 

Что я делаю не так? Кто знает, кто опытный?

 

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

да, нечто такое было. 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" итд

 

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Закрываю тему. Всем спасибо!

Я невнимательно читал документацию на 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.

вот оказывается не учел что её знак реверснут

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...