В следующем коде я пытаюсь получить местное время и среднеевропейское время и найти различие между ними. Но вывод показывает обоим, которые временные стоимости равны:
diff=0 iTm1=16:34 iTm2=16:34 <-----[gmtime is 13:34 actualy]
Когда я просто получаю gmtime, он работает правильно. Но когда я получаю и локальный и gmtime, gmtime становится равным localtime.
#include <stdio.h>
#include <time.h>
int main()
{
time_t iTime;
struct tm * iTm1;
struct tm * iTm2;
int iTimeDifferenceInMinutes;
time(&iTime);
iTm1=gmtime(&iTime);
iTm2=localtime(&iTime);
iTimeDifferenceInMinutes=(int)((iTm2->tm_hour - iTm1->tm_hour)) * 60;
printf("diff=%d iTm1=%d:%d iTm2=%d:%d\n", iTimeDifferenceInMinutes,
iTm1->tm_hour, iTm1->tm_min,
iTm2->tm_hour, iTm2->tm_min);
}
У меня есть ошибка, но я не мог найти его... Пусть кто-то покажет мне мой отказ..?
Всем спасибо! Я понимаю свою проблему. Думаю, было бы лучше, если бы я не использовал _r-версии функций времени, потому что у меня программа будет работать на встроенном устройстве (несколько платформ), и я не знаю, поддерживаются ли инструментальные цепочки для реентерабельных функций. достаточно.
Еще раз спасибо.
Каждая из функций gmtime
и localtime
возвращает указатель на фиксированный буфер. Кажется, что в вашей реализации они используют один и тот же буфер, поэтому вызов gmtime
заполняет этот буфер, а затем вызов localtime
заполняет этот буфер другими данными.
Если у вас есть gmtime_r
и localtime_r
, используйте их. (Вам может потребоваться включить строку #define _POSIX_SOURCE
или что-то подобное перед #include
). Вам потребуется выделить память для двух struct tm
объектов.
struct tm local_tm, gm_tm;
time(&iTime);
gmtime_r(&iTime, &gm_tm);
localtime_r(&iTime, &local_tm);
В старых системах нет версий _r
(они были добавлены, потому что простые версии не могут быть легко использованы в многопоточной программе). Затем вам нужно скопировать данные перед следующим вызовом любой из двух функций.
struct tm local_tm, gm_tm;
time(&iTime);
memcpy(&gm_tm, gmtime(&iTime), sizeof(gm_tm));
memcpy(&local_tm, localtime(&iTime), sizeof(local_tm));
Ваша ошибка в использовании указателей на struct tm
без фактического наличия переменной, содержащей память. Вот исправленная версия:
#include <stdio.h>
#include <time.h>
int main()
{
time_t iTime;
struct tm iTm1;
struct tm iTm2;
int iTimeDifferenceInMinutes;
time(&iTime);
iTm1=*gmtime(&iTime);
iTm2=*localtime(&iTime);
iDiff=(int)((iTm2.tm_hour - iTm1.tm_hour)) * 60;
printf("diff=%d iTm1=%d:%d iTm2=%d:%d\n", iDiff,
iTm1.tm_hour, iTm1.tm_min,
iTm2.tm_hour, iTm2.tm_min);
}
Цитата из справочной страницы Linux:
Функция gmtime () [... snip ...] возвращаемое значение указывает на статически выделенную структуру, которая может быть перезаписана последующими вызовами любые функции даты и времени. Функция gmtime_r () делает то же самое, но сохраняет данные в предоставленная пользователем структура.
Функция localtime () [... snip ...] Возвращаемое значение указывает на статически выделенная структура, которая может быть перезаписана последующими вызовами любой функции даты и времени. Функция localtime_r () делает то же самое, но сохраняет данные в предоставленной пользователем структуре. Это не нужно установить tzname.
И localtime, и gmtime используют статическую память в clib для своей обработки. Поэтому, когда вы используете один, он перезаписывает предыдущий вызов.
Вам нужно вызвать gmtime, затем извлечь нужные переменные и сохранить их в отдельном месте. Затем позвоните в местное время и сравните.
ИЛИ вы можете использовать реентерабельные версии этих вызовов (localtime_r, gmtime_r), которые вы должны предоставить вашей собственной памяти, но перезаписи данных не произойдет.
Я рекомендую привыкнуть к использованию реентерабельных версий этих вызовов, тогда такие ошибки не покажут свою уродливую голову!