Получение местного и гринвичского времени - PullRequest
1 голос
/ 01 августа 2010

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

diff=0 iTm1=16:34 iTm2=16:34 <-----[gmtime is 13:34 actualy]

Когда я просто получаю gmtime, он работает правильно. Но когда я получаю локальное и gmtime, gmtime становится равным местному времени.

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

У меня ошибка, но я не смог ее найти ... Может кто-нибудь покажет мне мою ошибку, пожалуйста ..?

Ответы [ 5 ]

1 голос
/ 01 августа 2010

Ваша ошибка в использовании указателей на 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 голос
/ 01 августа 2010

Функции gmtime и localtime возвращают указатель на фиксированный буфер. Похоже, что в вашей реализации они используют один и тот же буфер, поэтому вызов gmtime заполняет этот буфер, а затем вызов localtime заполняет этот буфер другими данными.

Если у вас есть gmtime_r и localtime_r, используйте их. (Возможно, вам придется включить строку #define _POSIX_SOURCE или что-то подобное перед #include <time.h>). Вам нужно будет выделить память для двух 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));
0 голосов
/ 01 августа 2010

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

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

0 голосов
/ 01 августа 2010

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

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

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

0 голосов
/ 01 августа 2010

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

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...