Войти в систему

Home
    - Создать дневник
    - Написать в дневник
       - Подробный режим

LJ.Rossia.org
    - Новости сайта
    - Общие настройки
    - Sitemap
    - Оплата
    - ljr-fif

Редактировать...
    - Настройки
    - Список друзей
    - Дневник
    - Картинки
    - Пароль
    - Вид дневника

Сообщества

Настроить S2

Помощь
    - Забыли пароль?
    - FAQ
    - Тех. поддержка



Пишет dibr ([info]dibr)
@ 2012-07-01 12:56:00


Previous Entry  Add to memories!  Tell a Friend!  Next Entry
time_t
     [info]ilya_314@lj сообщает - проблемы с 61-й секундой на линуксе таки возникли :-) Ещё тут в комментах мне сообщили, что в линуксе есть поддержка leap seconds, а я предположил, что это вполне может привести к глюкам (хотя и не очень на это рассчитывал). Однако, "они смогли" :-)

     А мне вот что интересно. В стандартной библиотеке языка Си (далее libc) есть поддержка двух типов времени: "календарного" (вида "число-месяц-год-час-минута-секунда", удобно использовать при взаимодействии с пользователем или выяснении "ночь сейчас или день?!" - далее будем называть этот тип tm), и "линейного" (число секунд, прошедшее от "начала эпохи", удобно для хранения (это просто число) и расчёта промежутков времени - далее time_t). Разумеется, есть процедуры преобразования time_t в tm и обратно (для простоты забудем пока про местное время). Без учёта високосной секунды там всё тривиально - календарь известен на сотни лет вперёд, формула пересчёта известна и неизменна со времён появления этой самой libc :-)
     А теперь мы хотим поддержать високосную секунду. Секунда эта вводится "по мере возникновения потребности", расписать её на сто лет вперёд не получается, значит учёт каждой конкретной високосной секунды придётся делать "апдейтом" - явным изменением кода для учёта именно этой секунды. И возникает вопрос:
     А как оно там в линуксе-то сделано? Каждые несколько лет меняется формула пересчёта time_t в tm? Но тогда возможна куча спецэффектов - начиная с того, что в этом случае time_t этой системы будет отличаться от time_t систем, не учитывающих високосную секунду (винда, тот же линукс, но без апдейта для именно этой секунды), а значит time_t нельзя будет использовать для обмена информацией о времени; и заканчивая всякими банальностями вроде того, что в момент добавления високосной секунды изменится "чётность" секунд в time_t (например, чётная "секунда-в-минуте" будет соответствовать нечётному time_t), ну, или что добавив к time_t 3600 секунд - приложение может оказаться не "ровно через час отсюда", а "через час без одной секунды". Или процедура пересчёта "заморожена", а високосная секунда вводится только в виде появления "23:59:60" в tm? Но это вообще некорректно - тогда возникнет момент времени, который непредставим в time_t, со всеми вытекающими последствиями. И я понимаю, почему винда решила не париться, и все эти секунды не учитывать: погрешность в одну секунду мало кому важна, а кому реально важна - те вряд ли понадеются на поддержку системой, и поддержат это сторонними средствами.

     А на самом-то деле как оно в линуксе, интересно?..


(Добавить комментарий)


[info]vlkamov@lj
2012-07-01 07:11 (ссылка)
> В стандартной библиотеке языка Си (далее libc) ( есть поддержка двух типов времени )
В Юниксовом посекундном цикле 32 года. Если начало каждых суток обозначить отсчетом юниксового таймера в виде
tttttttt YYYYMMddhhmmss
то всего на 32 года выйдет файл меньше 300 килобайт. Даже слегка упакованный он ужмется до 50-70 килобайт. Утилиты по переводу часов обычно больше.
Таймер/календарь после 23:59:59 не ставит 00:00:00, а тупо берет из этого файла установленное там время и дату. Автоматически учитываются високосные годы, переводы на летнее/зимнее время, и даже вот эта вот секунда.
В случае каких-либо пертурбаций достаточно заменить этот файл на новую версию, что не требует никакой разработки, компиляции и совместимо с любыми ОС. Даже кодировка не важна.
Полагаю это решение уже звучало в стандартизующих кругах - уж очень очевидно, но решиться заменить дорогие сердцу программы на тупой текст смогут еще не скоро.

(Ответить) (Ветвь дискуссии)


[info]dibr@lj
2012-07-01 09:35 (ссылка)
> В Юниксовом посекундном цикле 32 года

Мысль не понял. А что произойдёт через 32 года? И вообще - что такое "юниксовый посекундный цикл"?

32-битное time_t, если речь о нём, имеет "цикл" 136 лет, и переполнится в 2038 году (68 лет от "начала эпохи"). Переполнение time_t - вообще говоря, проблема, но "программисты в курсе", решается она тупой заменой int32 на int64, а поскольку за это время сменится минимум пара поколений софта, и новый софт будут собирать уже с 64-битным time_t - решится она сама, до её возникновения (много у вас есть реально используемого софта более чем 20-литней давности)?

> то всего на 32 года выйдет файл меньше 300 килобайт. Даже слегка упакованный он ужмется до 50-70 килобайт

А в сервисе, считающем время, делать распаковку и поиск, ага. Или вообще базу данных забубенить, лучше почасовую - вдруг где решат ввести дополнительную миллисекунду в конце часа :-)
Я бы предложил, если речь идёт о стандартизации, ввести что-то вроде "нескольких функций на стандартном интепретируемом языке", которые и описывали бы перевод времени туда-сюда. При появлении всяких там "секунд" подменяется файл (стандартизованного формата) с описаниями этих функций, а уже ОС/сервисы его интерпретируют и обсчитывают время по новому.
Радость тут даже не в экономии сотни килобайт - они и правда не настолько уж критичны - а в некоторой "человекочитаемости" результата. Да и не всем нравится, когда вместо "формулы" на ровном месте появляется упакованный бинарник...

(Ответить) (Уровень выше) (Ветвь дискуссии)


[info]vlkamov@lj
2012-07-01 10:29 (ссылка)
Я глянул в в первый попавшийся источник, там было 32 года. Пусть 136 или 146 - неважно, больше 20 лет все равно не нужно. Правда неясно в чем состоял недавний кипеж.
Но это все в стороне от главного.

Функции - это извращение описываемого метода, соль которого: только текст и только цифрами, стандартизация которых проведена давно, надолго и для всех одинаково.

(Ответить) (Уровень выше)


[info]starcat13@lj
2012-07-01 09:02 (ссылка)
Они просто забили:

Unix time, or POSIX time, is a system for describing instances in time, defined as the number of seconds that have elapsed since midnight Coordinated Universal Time (UTC), January 1, 1970, not counting leap seconds
....

Observe that when a positive leap second occurs (i.e., when a leap second is inserted) the Unix time numbers repeat themselves. The Unix time number 915 148 800.50 is ambiguous: it can refer either to the instant in the middle of the leap second, or to the instant one second later, half a second after midnight UTC. In the theoretical case when a negative leap second occurs (i.e., when a leap second is deleted) no ambiguity is caused, but instead there is a range of Unix time numbers that do not refer to any point in time at all.

А кому надо - считайте сами и/или пользуйтесь другими средствами:

However, where leap seconds occur, such calculations give the wrong answer. In applications where this level of accuracy is required, it is necessary to consult a table of leap seconds when dealing with Unix times, and it is often preferable to use a different time encoding that does not suffer this problem.

(Ответить) (Ветвь дискуссии)


[info]dibr@lj
2012-07-01 09:38 (ссылка)
Ха. И они удивляются, что когда к этому скотчем приматывается "поддержка leap seconds" (в результате чего появляются моменты времени, валидные с точки зрения ОС, но невалидные с точки зрения libc) - программы начинают падать?
Виндовый подход (игнорировать так игнорировать) мне как-то ближе :-)

(Ответить) (Уровень выше)