Получение локального и среднеевропейское время

В следующем коде я пытаюсь получить местное время и среднеевропейское время и найти различие между ними. Но вывод показывает обоим, которые временные стоимости равны:

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);
}

У меня есть ошибка, но я не мог найти его... Пусть кто-то покажет мне мой отказ..?

1
задан kennytm 1 August 2010 в 14:13
поделиться

5 ответов

Всем спасибо! Я понимаю свою проблему. Думаю, было бы лучше, если бы я не использовал _r-версии функций времени, потому что у меня программа будет работать на встроенном устройстве (несколько платформ), и я не знаю, поддерживаются ли инструментальные цепочки для реентерабельных функций. достаточно.

Еще раз спасибо.

0
ответ дан 2 September 2019 в 22:32
поделиться

Каждая из функций 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));
1
ответ дан 2 September 2019 в 22:32
поделиться

Ваша ошибка в использовании указателей на 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);
}
1
ответ дан 2 September 2019 в 22:32
поделиться

Цитата из справочной страницы Linux:

Функция gmtime () [... snip ...] возвращаемое значение указывает на статически выделенную структуру, которая может быть перезаписана последующими вызовами любые функции даты и времени. Функция gmtime_r () делает то же самое, но сохраняет данные в предоставленная пользователем структура.

Функция localtime () [... snip ...] Возвращаемое значение указывает на статически выделенная структура, которая может быть перезаписана последующими вызовами любой функции даты и времени. Функция localtime_r () делает то же самое, но сохраняет данные в предоставленной пользователем структуре. Это не нужно установить tzname.

0
ответ дан 2 September 2019 в 22:32
поделиться

И localtime, и gmtime используют статическую память в clib для своей обработки. Поэтому, когда вы используете один, он перезаписывает предыдущий вызов.

Вам нужно вызвать gmtime, затем извлечь нужные переменные и сохранить их в отдельном месте. Затем позвоните в местное время и сравните.

ИЛИ вы можете использовать реентерабельные версии этих вызовов (localtime_r, gmtime_r), которые вы должны предоставить вашей собственной памяти, но перезаписи данных не произойдет.

Я рекомендую привыкнуть к использованию реентерабельных версий этих вызовов, тогда такие ошибки не покажут свою уродливую голову!

0
ответ дан 2 September 2019 в 22:32
поделиться
Другие вопросы по тегам:

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