Короткий ответ: нет, практически говоря, gmtime_r никогда не заполнит tm_sec значением 60. Это печально, но неизбежно.
Фундаментальная проблема заключается в том, что time_t в соответствии со стандартом Posix представляет собой количество секунд с 01 января 1970 года по всемирному координированному времени, при условии отсутствия високосных секунд.
В течение последней дополнительной секунды прогресс был таким:
1483228799 2016-12-31 23:59:59
1483228800 2017-01-01 00:00:00
Да, там должна была быть дополнительная секунда, 23:59:60. Но нет никакого возможного значения time_t между 1483228799 и 1483228800.
Я знаю два способа для варианта gmtime вернуть время, заканчивающееся на :60:
Вы можете запустить часы вашей ОС на чем-то другом, кроме UTC, обычно TAI или TAI-10, и использовать так называемые «правильные» часовые пояса для преобразования в UTC (или местное время) для отображения. См. эту веб-страницу для обсуждения этого вопроса.
Вы можете использовать clock_gettime() и определить новое значение clkid, возможно, CLOCK_UTC, которое решает проблему time_t, используя при необходимости преднамеренно ненормализованные значения struct timespec. Например, способ получить значение времени между 1483228799 и 1483228800 состоит в том, чтобы установить tv_sec в 1483228799, а tv_nsec в 1000000000. Дополнительную информацию см. на этой веб-странице.
Способ № 1 работает очень хорошо, но никто не использует его, потому что никто не хочет запускать часы ядра на чем-то другом, кроме UTC, как это должно быть. (В конечном итоге у вас возникают проблемы с такими вещами, как временные метки файловой системы и такие программы, как tar, которые встраивают эти временные метки.)
Способ № 2 — прекрасная идея, ИМО, но, насколько мне известно, она никогда не была реализована в выпущенной ОС. (Случилось так, что у меня есть работающая реализация для Linux, но я еще не выпустил свою работу.) Чтобы способ № 2 работал, вам нужен новый вариант gmtime, возможно, gmtime_ts_r, который принимает struct timespec вместо time_t.
Приложение: Я только что перечитал заголовок вашего вопроса. Вы спросили: «Будет ли gmtime() сообщать о 60 секундах, когда сервер находится в високосной секунде?» Мы могли бы ответить на это, сказав «да, но» с оговоркой, что, поскольку большинство серверов не могут правильно представлять время в течение дополнительной секунды, они никогда не «на» дополнительную секунду.
Приложение 2: я забыл упомянуть, что схема № 1 работает лучше для местного времени, то есть, когда вы вызываете один из вариантов localtime, чем для времени UTC и gmtime. Очевидно, что на преобразования, выполняемые localtime, влияет установка переменной окружения TZ, но не совсем ясно, влияет ли TZ на gmtime. Я заметил, что на некоторые реализации gmtime влияет TZ, и поэтому они могут делать дополнительные секунды в соответствии с «правильными» зонами, а некоторые не могут. В частности, gmtime в GNU glibc, по-видимому, обращает внимание на информацию о дополнительных секундах в «правильная» зона, если TZ указывает ее, тогда как gmtime в распространении tzcode IANA этого не делает.
person
Steve Summit
schedule
17.02.2018
gmtimeсправится с этим. - person Yuki   schedule 18.02.2018