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

Здравствуйте!

Как учитывается временная зона в стандартной библиотеке времени time.h?

Все что нашел в файле time.h - упоминание в функции strftime()

%Z is replaced by the timezone name or abbreviation, or by no characters if no time zone is determinable.

Попробовал все, что можно вывести, выводит все, кроме временной зоны:

time_t rawtime = 1480685759; // Fri, 02 Dec 2016 13:35:59 GMT

struct tm * timeinfo;

timeinfo = (struct tm*)localtime(&rawtime); // Convert time_t to tm as UTC time

char buffer [80];

 

strftime (buffer,80,"%I:%M%p",timeinfo);

puts (buffer); // 01:35PM

 

strftime (buffer,80,"%H:%M:%S%p",timeinfo);

puts (buffer); // 13:35:59PM

 

strftime (buffer,80,"%H:%M:%S",timeinfo);

puts (buffer); // 13:35:59

 

strftime (buffer,80,"%d.%m.%y",timeinfo);

puts (buffer); // 02.12.16

 

strftime (buffer,80,"%a_%A",timeinfo);

puts (buffer); // Fri_Friday

 

strftime (buffer,80,"%b_%B",timeinfo);

puts (buffer); // Dec_December

 

strftime (buffer,80,"%c",timeinfo);

puts (buffer); // 02 Dec 2016 13:35:59

 

strftime (buffer,80,"%j",timeinfo);

puts (buffer); // 337 (day of the year as a decimal number (001-366))

 

strftime (buffer,80,"%W",timeinfo);

puts (buffer); // 48 (the week number of the year (Monday as the first day))

 

strftime (buffer,80,"%x",timeinfo);

puts (buffer); // 02 Dec 2016

 

strftime (buffer,80,"%X",timeinfo);

puts (buffer); // 13:35:59

 

strftime (buffer,80,"%y",timeinfo);

puts (buffer); // 16 (year without century).

 

strftime (buffer,80,"%Y",timeinfo);

puts (buffer); // 2016 (year with century)

 

strftime (buffer,80,"%Z",timeinfo);

puts (buffer); // ???

Не знаю, как её задавать. Ведь с систем синхронизации будет время UTC+0, а у меня локальное UTC+3. Т.е. где-то должна быть временная зона.

 

Посмотрел у других - для PIC24 (компилятор XC16) в файле time.h есть переменная time_zone:

extern int    time_zone;    /* minutes WESTWARD of Greenwich */
                /* this value defaults to 0 since with
                   operating systems like MS-DOS there is
                   no time zone information available */

Изменено пользователем Pridnya

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


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

Уже давненько(!), мне понадобилось то же самое (у меня тоже KEIL), и я обнаружил, что функции есть, а реализации - нет. Пришлось финтить: заводить свою константу настройки и добавлять 3600*n, где n[-a..+b], при выдаче UTC time_t "наружу" и, соответственнно, вычитать такую же константу при установке времени в системе из значения локального времени "снаружи". Поскольку код стар (даже суперстар ;)), я уже и не копал, что там в библиотеках в KEIL 5.x, но есть у меня нехорошее подозрение... Интересное начинается, когда еще и зимнее/летнее время надо учитывать. У вас в России хоть этого уже нет: этим можете еще похвастаться.

 

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


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

Уже давненько(!), мне понадобилось то же самое (у меня тоже KEIL), и я обнаружил, что функции есть, а реализации - нет. Пришлось финтить: заводить свою константу настройки и добавлять 3600*n, где n[-a..+b], при выдаче UTC time_t "наружу" и, соответственнно, вычитать такую же константу при установке времени в системе из значения локального времени "снаружи". Поскольку код стар (даже суперстар ;)), я уже и не копал, что там в библиотеках в KEIL 5.x, но есть у меня нехорошее подозрение... Интересное начинается, когда еще и зимнее/летнее время надо учитывать. У вас в России хоть этого уже нет: этим можете еще похвастаться.

 

Для учета летнего и зимнего времени в стандартной библиотеке есть поле Daylight Savings Time flag, но я пока не проверял как оно работает, т.к. перевода времени на летнее и зимнее у нас нет:

struct tm {
    int tm_sec;   /* seconds after the minute, 0 to 60
                     (0 - 60 allows for the occasional leap second) */
    int tm_min;   /* minutes after the hour, 0 to 59 */
    int tm_hour;  /* hours since midnight, 0 to 23 */
    int tm_mday;  /* day of the month, 1 to 31 */
    int tm_mon;   /* months since January, 0 to 11 */
    int tm_year;  /* years since 1900 */
    int tm_wday;  /* days since Sunday, 0 to 6 */
    int tm_yday;  /* days since January 1, 0 to 365 */
    int tm_isdst; /* Daylight Savings Time flag */
    union {       /* ABI-required extra fields, in a variety of types */
        struct {
            int __extra_1, __extra_2;
        };
        struct {
            long __extra_1_long, __extra_2_long;
        };
        struct {
            char *__extra_1_cptr, *__extra_2_cptr;
        };
        struct {
            void *__extra_1_vptr, *__extra_2_vptr;
        };
    };
};

а вот для временной зоны его нет. Есть какие-то поля "ABI-required extra fields, in a variety of types" , но я не знаю зачем они и как их использовать.

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


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

Вбил в поиск по хелпу кейла слово "timezone" и получил неутешительный ответ:

Timezone

Not supported by the ARM C library.

 

 

Так что пишите свои костыли, раз уж надо...

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


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

Вбил в поиск по хелпу кейла слово "timezone" и получил неутешительный ответ:

 

Так что пишите свои костыли, раз уж надо...

Спасибо! Посмотрел, в каком документе упоминается:

ARM® Compiler toolchain

Version 5.02

Using ARM C and C++ Libraries and Floating-Point Support.

 

Затем посмотрел, а как в других библиотеках, у Microchip в time.h XC32 Compiler, есть

extern int    time_zone;

и примечание:

No standard mechanism exists for setting the current timezone, or the rules for when Daylight Saving Time (DST) is in effect.

In this implementation, as in others, you can specify both with an environment variable such as TZ or TIMEZONE.

Получается, что нужно самому корректировать, прибавлять к счетчику три часа для UTC+3.

Изменено пользователем Pridnya

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


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

Получается, что нужно самому корректировать, прибавлять к счетчику три часа для UTC+3.

А Вы хотели, чтобы само прибавлялось? Да еще и с учетом постоянного перкероения часовых поясов?

 

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


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

А Вы хотели, чтобы само прибавлялось? Да еще и с учетом постоянного перкероения часовых поясов?

Я предполагал, что в стандартной библиотеке есть некая константа timezone = 3, которая учитывается при работе библиотеки - к UnixTime UTC+0 (время с NTP-сервера) прибавляется timezone*SecPerHour и получаем местное время UTC+3. Мне казалось, что операция стандартная и должна быть в стандартной библиотеке. Оказалось, что исторически так сложилось, что коррекция не поддерживается в стандартной библиотеке.

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


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

Я полностью написал свою библиотеку. Там мизер, по сути. У меня и летнее время подключается/ отключается.

Проверял в инете типа http://www.bl2.ru/programing/timestamp.html

 

Часовой пояс важен, так как некоторые SCADA не совсем корректно себя ведут. Я сталкивался. Часть SCADA напрямую часовой пояс выгребают с компа. Для одной ничего не смогли сделать. Просто выбрали на приборе Timezone = 0.

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


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

Я полностью написал свою библиотеку. Там мизер, по сути. У меня и летнее время подключается/ отключается.

Проверял в инете типа http://www.bl2.ru/programing/timestamp.html

 

Часовой пояс важен, так как некоторые SCADA не совсем корректно себя ведут. Я сталкивался. Часть SCADA напрямую часовой пояс выгребают с компа. Для одной ничего не смогли сделать. Просто выбрали на приборе Timezone = 0.

Посмотрел ваш онлайн-калькулятор: "Время на вашем компьютере" в онлайн калькуляторе и на моем компьютере отличается на час (онлайн калькулятор ошибается - пишет что у меня 12:46, а у меня 13:46, что совпадет с временем сервера в онлайн-калькуляторе). Время UTC+0 совпадает с временем, которое я читаю с публичного NTP-сервера. На разницу в секндах не обращайте внимание - это я переключался между программами.

PS: У меня тоже UTC+3, как в онлайн-калькуляторе.

post-62159-1481021481_thumb.png

post-62159-1481021702_thumb.png

Изменено пользователем Pridnya

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


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

Я написал "типа этого". Специально проверял по разным. У меня всё работает. Уже 2 года выпускают изделие.

Вообще непонятно как там можно ошибиться.

Когда будете писать, контролируйте при GMT 0. А TimeZone это просто смещение. Ошибиться в операции сложения... ну я не знаю. ))

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


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

Я написал "типа этого". Специально проверял по разным. У меня всё работает. Уже 2 года выпускают изделие.

Вообще непонятно как там можно ошибиться.

Когда будете писать, контролируйте при GMT 0. А TimeZone это просто смещение. Ошибиться в операции сложения... ну я не знаю. ))

Я скриншоты привел для того, чтобы вы в своем онлайн-калькуляторе поискали, почему он пишет, что у меня на компьютере время такое-то, а оно на час отличается. У вас, наверное, ошибка, ведь часовые пояса у меня и у вас совпадают +3. Время на моем компьютере совпадает с "временем сервера", а не с "временем на вашем компьютере". :rolleyes: Или я чего-то не понял?

 

Как прибавить три часа (3*3600) к UnixTime я знаю.

Изменено пользователем Pridnya

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


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

Я скриншоты привел для того, чтобы вы в своем онлайн-калькуляторе поискали, почему он пишет, что у меня на компьютере время такое-то, а оно на час отличается.

У вас написано, что часовой пояс у вашего компьютера - Калининградское время (зима), а это как раз -1 час т.е. ваш winxp уже давно не знает правильного часового пояса, поищите в инете как это поправить через реестр.

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


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

У вас написано, что часовой пояс у вашего компьютера - Калининградское время (зима), а это как раз -1 час т.е. ваш winxp уже давно не знает правильного часового пояса, поищите в инете как это поправить через реестр.

Спасибо! Сделал все как здесь описано, теперь время с онлайн-калькулятором совпадает (только секунды не синхронизированы, но это уже другой вопрос).

post-62159-1481051452_thumb.png

post-62159-1481051518_thumb.png

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


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

Извините, то есть стандартизированного и документированного для Кейла пути работы с летним-зимним временем нет? И каждый свое делает как Бог на душу положит?

Грустно как-то. Нужно добавить в сорцы работу с летним/зимним- думал что лыжи не едут, а оказывается лыж просто нет совсем.

 

Ну хорошо, врукопашную.

А кто как даты перевода задает?

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

 

И, получается, что лучше просто иметь в конфиге startDateTime и endDateTime.

 

Или есть более изящный путь, без обновления этого конфига раз в год, определить какое сейчас здесь время, летнее или нелетнее?

Например, указать сайт, показывающий локальное время для данного прибора, и от него уже отталкиваться при определении времени? Или что-то подобное?

 

А еще: я, конечно, в школе учил географию, но как-то не думал, что переход на летнее время может быть в конце календарного года, а на зимнее- в начале года. Интересно, многие ли разработчики программ про это думали и учитывали в сорцах :)

 

PS вот что бывает когда десятки лет работаешь в UTC, и вдруг надо в что-то местное переводить... Столько нового узнаешь об окружающем мире....

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


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

А еще: я, конечно, в школе учил географию, но как-то не думал, что переход на летнее время может быть в конце календарного года, а на зимнее- в начале года. Интересно, многие ли разработчики программ про это думали и учитывали в сорцах :)

Делал в своё время.

По памяти: у нас были следующие варианты задания в конфиге диапазона летнего времени:

1.Фиксированное число/месяц.

2.Последняя суббота N-го месяца.

3.Первая суббота N-го месяца (хотя уже не помню - возможно можно было выбрать номер субботы определённого месяца).

Всё учитывали.

И перевод может быть на не целое число часов (полчаса например).

Да и не переводил вобщем-то реально ничего (RTC). Часы реального времени шли всегда в линейном времени.

А уже если нужно было сезонное время, я определял - попадает-ли данная дата в диапазон летнего времени и включен-ли перевод? Если да - прибавлял к линейному времени смещение.

А вообще - перевод часов в системе реального времени, когда многое завязано на часы - это ОЧЕНЬ нетривиальная задача. Очень много проблем было с этим связано.

Особенно - когда на эти переводы ещё накладываются корректировки времени по интерфейсам связи и корректировки хода часов с ФАПЧ.

Служба реального времени - была одной из наиболее сложных частей ПО.

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


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

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

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

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

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

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

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

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

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

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