UNIX time
UNIX-время или POSIX-время (англ. Unix time ) — способ кодирования времени, принятый в POSIX-совместимых операционных системах.
Моментом начала отсчёта считается полночь (по UTC) с 31 декабря 1969 года на 1 января 1970, время с этого момента называют «эрой UNIX» (англ. Unix Epoch ).
Время UNIX согласуется с UTC, в частности, при объявлении високосных секунд UTC соответствующие номера секунд повторяются.
Способ хранения времени в виде количества секунд очень удобно использовать при сравнении дат (с точностью до секунды), а также для хранения дат: при необходимости их можно преобразовать в любой удобочитаемый формат. Дата и время в этом формате также занимают очень мало места (4 или 8 байтов, в зависимости от размера машинного слова), поэтому его разумно использовать для хранения больших объёмов дат. Недостатки в производительности могут проявиться при очень частом обращении к элементам даты, вроде номера месяца и т. п. Но в большинстве случаев эффективнее хранить время в виде одной величины, а не набора полей.
Чтобы узнать текущее UNIX-время в большинстве UNIX-подобных систем, можно использовать команду date +%s .
13 февраля 2009 года в 23:31:30 по UTC (02:31:30 14 февраля по MSK) значение UNIX-времени достигло 1234567890 секунд.
19 января 2038 года в 03:14:08 по всемирному времени значение переменной типа time_t , отсчитывающей число секунд, прошедших с 1 января 1970 года, достигнет 2 31 , что может привести к ошибочной интерпретации этого числа как отрицательного. Возможное решение данной проблемы состоит в использовании не 32-битной, а 64-битной переменной для хранения времени, чего хватит ещё на 300 миллиардов лет.
См. также
Ссылки
Wikimedia Foundation . 2010 .
Полезное
Смотреть что такое «UNIX time» в других словарях:
- Unix time — Unix time, or POSIX time, is a system for describing points in time, defined as the number of seconds elapsed since midnight Coordinated Universal Time (UTC) of January 1 1970, not counting leap seconds. It is widely used not only on Unix like… … Wikipedia
- Unix time — Эта статья о формате кодирования времени; об утилите см.: time (Unix). UNIX время или POSIX время (англ. Unix time) способ кодирования времени, принятый в POSIX совместимых операционных системах. Моментом начала отсчёта считается полночь (по… … Википедия
- Unix — (officially trademarked as UNIX, sometimes also written as Unix with small caps) is a computer operating system originally developed in 1969 by a group of AT T employees at Bell Labs, including Ken Thompson, Dennis Ritchie, Douglas McIlroy, and… … Wikipedia
- UNIX — Ken Thompson und Dennis Ritchie Basisdaten Entwickler … Deutsch Wikipedia
- Unix — Kommandozeile (Unix Prompt) Basisdaten Entwickler Ken Thompso … Deutsch Wikipedia
- UNIX version 6 — UNIX version 6, appelé en anglais Sixth Edition Unix, Version 6 Unix ou Unix time sharing system 6, fut la première version du système d exploitation UNIX à être largement répandue en dehors des laboratoires Bell où elle fut conçue. Elle sortit… … Wikipédia en Français
- Time (Unix) — time is a command in the Unix operating systems. It is used to determine the duration of execution of a particular command.UsageTo use the command, simply precede any command by the word time, such as:time lsWhen the command completes, time will… … Wikipedia
- Unix — (registrado oficialmente como UNIX®) es un sistema operativo portable, multitarea y multiusuario; desarrollado, en principio, en 1969 por un grupo de empleados de los laboratorios Bell de AT T, entre los que figuran Ken Thompson, Dennis Ritchie y … Wikipedia Español
- Time t — The time t datatype is a data type in the ISO C library defined for storing system time values. Such values are returned from the standard time() library function. This type is a typedef defined in the standard lt;time.h gt; header. ISO C defines … Wikipedia
- UNIX-Derivat — Grobe Übersicht über die Entwicklung und Abstammung der größten Unix Derivate 1965 wurden im Rahmen der Fall Joint Computer Conference einige Aufsätze[1] über ein neu zu erstellendes Betriebssystem namens Multics veröffentlicht. Hinter Multics… … Deutsch Wikipedia
- Обратная связь: Техподдержка, Реклама на сайте
- Путешествия
Экспорт словарей на сайты, сделанные на PHP,
WordPress, MODx.
- Пометить текст и поделитьсяИскать в этом же словареИскать синонимы
- Искать во всех словарях
- Искать в переводах
- Искать в ИнтернетеИскать в этой же категории
Время — иллюзия, время Unix — иллюзия вдвойне…
Как вы хорошо знаете, в Unix-системах мы измеряем время как количество секунд, прошедших с «эпохи»: 00:00:00 UTC 1 января 1970 года. Немало людей сильно разозлилось из-за этого, да и вообще, общественное мнение сочло это ошибкой.
Во-первых, это определение основано не на чём-то разумном, например, на объективной частоте колебаний атома цезия-133, а на удобной доле времени полного оборота одного большого камня вокруг собственной оси.
Во времени Unix каждый день гарантированно состоит из 86400 секунд и мы притворяемся, что это число равномерно увеличивается. Когда оказывается, что вышеупомянутый камень на самом деле вращался дольше, чем удобно для нас, и нам нужно добавить секунду координации, то мы просто притворяемся, что этого не было, а механизм меток времени не идентифицирует уникальный момент времени.
Ещё один аспект, который продолжает вызывать проблемы, когда мы пытаемся считать секунды, заключается в том, что мы сталкиваемся с проблемами хранения и описания данных, потому что, как оказалось, компьютеры не так уж хорошо справляются с числами. Не говоря уж об «эпохальном сбое».
Как же мы к этому пришли? Всё началось в 1971 году, когда в в первом издании руководства для программиста Unix было дано определение времени Unix как «времени с 00:00:00 1 января 1971 года, измеряемого в шестидесятых долях секунды«:
Именно так, изначально эпохой Unix было 1971-01-01T00:00:00 . Вы спросите, какого часового пояса? Ну, это точно не был «UTC», потому что он заменит GMT в качестве стандартного времени только в 1972 году. Во-вторых, обратите внимание, что время измерялось в 1/60 секунды, а не в секундах. Зачем же так сделали?
Вспомним, что в то время Unix разрабатывался в США на PDP-11. Эти системы имели часы линейного времени (Line-Time Clock, LTC), использующие частоту питания переменного тока для генерации прерывания для процессора. Тогда это прерывание использовалось для обновления системных часов.
Забавно здесь то, что эта частота прерываний зависит от частоты в сети источника питания. В основной части Азии и Европы эта частота равна 50 Гц, однако в США Westinghouse Electric Corporation (конкурент Томаса Эдисона и General Electric; любопытный факт: позже Westinghouse приобрела CBS, а затем была куплена Viacom) заметила, что использовавшиеся тогда дуговые лампы с угольным электродом меньше мерцают при 60 Гц, а поэтому стандартизировала эту частоту.
(Странный побочный эффект этого различия между США и Европой заключается в том, что в Японии используются обе частоты: на западе, где первые генераторы были куплены у немецкой AEG и установлены в Токио, частота в сети равна 50 Гц; на востоке, в Осаке, были установлены генераторы G.E., и используются 60 Гц. В результате этого в стране теперь работает множество высоковольтных линий постоянного тока для преобразования электричества между двумя регионами!)
Электросеть Японии
Итак, в первом издании UNIX измерял время на этих 60 Гц с хранением в 32-битных integer, таким образом имея возможность учитывать только 2^32 / 60 тактов/с * 60 с/мин * 60 мин/ч * 24 ч/д * 365 д/г = 2,3 лет , как и написано в руководстве. Несколько позже в том же 1971 году измерению времени было дано другое определение, оно учитывалось в секундах и могло описывать до 136 лет. Датой же эпохи Unix был достаточно произвольно выбран 1970 год (вопреки распространённому заблуждению о том, что она обозначает дату рождения Unix):
«В то время у нас не было плёночных накопителей, работала пара файловых систем, и мы постоянно меняли начало отсчёта времени. Поэтому в конце концов мы сказали: давайте выберем что-то одно, что достаточно долго не будет переполняться. Нас вполне устроил 1970 год», — сказал он.
(Истинная дата рождения Unix приходится примерно на 1969 год, когда Кен Томпсон портировал «Space Travel» на PDP-7, поэтому легко понять, почему эпоха Unix кажется обозначением рождения Unix.)
Секунды координации
Итак, теперь у нас есть 32-битный счётчик секунд от эпохи, который равномерно увеличивает значение с частотой 1 Гц и гарантирует нам, что будет насчитывать ровно 86400 секунд в любой 24-часовой период. Однако наш космический булыжник отсчёта замедляется в своём вращении, поэтому время от времени это число нужно изменять.
Для этого Международная служба вращения земли (IERS) отправляет всем Повелителям Времени электронные письма, сообщающие, должна или нет добавляться секунда координации:
Сегодня мы не можем винить время эпохи Unix за то, что оно изначально не учитывало секунды координации, потому что их не существовало до 1972 года. С тех пор (на 2022 год) произошло уже 27 положительных секунд координации, последняя из которых была введена в конце 2016 года. Каждый раз, когда происходит секунда координации, время эпохи Unix просто притворяется, что этого не было, из-за чего две даты соответствуют одной метке времени эпохи (epoch-time.c):
From epoch to time, via gmtime(3) to strftime(3): 1483228798 2016-12-31T23:59:58 1483228799 2016-12-31T23:59:59 //здесь отсутствующая секунда координации 1483228800 2017-01-01T00:00:00 From time to epoch, via strptime(3) to mktime(3): 2016-12-31T23:59:58 is 1483228798 2016-12-31T23:59:59 is 1483228799 2016-12-31T23:59:60 is 1483228800 2017-01-01T00:00:00 is 1483228800 //здесь дублирующаяся метка времени
(И давайте не забывать обо всех отрицательных секундах координации и тот факт, что некоторые системы Unix определяют диапазон tm_sec как [0-61] , учитывая мифическую «двойную секунду координации», которой на самом деле никогда не существовало.)
Хорошо в этом то, что всё это соответствует требованиям POSIX:
Значение, которое аппроксимирует количество секунд, прошедшее после эпохи.
Соотношение между истинным временем суток и текущим значением секунд после эпохи точно не установлено.
Способ внесения любых изменений в значение секунд после эпохи для согласования с нужным соотношением с текущим временем зависит от реализации. В формате секунд после эпохи каждый день насчитывает ровно 86400 секунд.
Проблема 2038 года
Даже при равномерном отсчёте и игнорировании секунд координации используемый для измерения секунд после эпохи тип данных time_t неизбежно придёт к переполнению. Хорошо, что есть стандарты, которые спасут нас в этой ситуации! Пусть POSIX не решает проблемы, но хорошо в стандартах то, что их много и можно выбрать подходящий, не так ли? Ох, постойте, в чём же дело? Давайте разберёмся.
Плохие новости: стандарты нас не спасут. Например, стандарт C гласит:
Диапазон и степень точности времени, представленного в clock_t и time_t, зависят от реализации.
Что ж, ладно. Имея 32-битный time_t , мы можем рассчитывать начиная с 1970 года примерно на 136 лет. Однако time_t является знаковым 32-битным integer, то есть у нас есть всего 68 лет в обоих направлениях, из-за чего возникает так называемая «Проблема 2038 года».
Она состоит в том, что самая большая дата, которую можно записать как time_t при помощи знакового 32-битного integer — это 2^31 — 1 = 2147483647 эпохи, или 2038-01-19T03:14:07Z:
Это легко исправить, правда? Мы «просто» изменяем тип данных time_t на знаковый 64-битный integer, что даёт нам теоретический максимум даты эпохи 2^63-1 = 9223372036854775807 после 1 января 1970 года. Как любят говорить люди, это значение задаёт дату примерно на 292 миллиарда лет в будущем, или примерно в 22 раз больше приблизительного возраста Вселенной, поэтому официально может считаться Чьей-то Чужой Проблемой.
Но — всегда есть «но», не правда ли? — действительно ли это произойдёт? Почему бы не попробовать и не проверить, как разные системы поведут себя, если мы передадим им для обработки не совсем логичные значения времени?
Оборот mktime(3)
Хотя время представлено в виде time_t , используется и другой популярный формат для записи разбитого на части времени — struct tm , из которого можно получить time_t , вызвав mktime(3) . В POSIX зафиксированы следующие элементы struct tm :
int tm_sec Seconds [0,60]. int tm_min Minutes [0,59]. int tm_hour Hour [0,23]. int tm_mday Day of month [1,31]. int tm_mon Month of year [0,11]. int tm_year Years since 1900. int tm_wday Day of week [0,6] (Sunday =0). int tm_yday Day of year [0,365]. int tm_isdst Daylight Savings flag.
Забавно в описанных здесь диапазонах то, что они в лучшем случае являются… рекомендательными. В POSIX конкретно написано:
… исходные значения [. ] компонентов не должны быть ограничены диапазонами, описанными в .
Так что же произойдёт, если передать mktime(2) тип struct tm со значениями вне этих диапазонов? Рассмотрим следующую программу:
int main() < struct tm t; time_t epoch; /* 2022-12-31 */ t.tm_year = 122; t.tm_mon = 11; t.tm_mday = 31; /* 22:57 */ t.tm_hour = 22; t.tm_min = 57; t.tm_sec = 3785; if ((epoch = mktime(&t)) == -1) < err(EXIT_FAILURE, "mktime"); >(void)printf("%s", ctime(&epoch)); return 0; > $ cc -Wall -Werror -Wextra t.c $ ./a.out Sun Jan 1 00:00:05 2023 $
Здесь перед присвоением tm_sec значения наш struct tm задавал дату December 31st, 22:57:00, 2022. Но потом мы присвоили tm_sec значение 3785 , то есть 1 час, 3 минуты и 5 секунд. Это приводит к тому, что выполняется инкремент tm_min на 3 минуты, что приводит к увеличению tm_hour на единицу. Затем мы ещё раз выполняем инкремент tm_hour (из оставшихся от tm_sec 3600 секунд), что приводит к оборачиванию этого значения на 00 и необходимости инкремента tm_mday . Теперь tm_mday оборачивается до 01 с инкрементом tm_year , и в результате мы получаем дату 2023-01-01T00:00:05 .
Такая нормализация меток времени становится ещё более запутанной, когда мы добавляем отрицательные значения (например, tm_mday = -1 означает предыдущий день tm_mon — 1 ) или (снова) при участии секунд координации, что может стать причиной головной боли. Лучше избегать такой ситуации.
Забавная date(1)
Давайте рассмотрим даты эпохи в момент или рядом с эпохой. Проигнорируем тот факт, что время эпохи до 1972 года определено не очень чётко, поскольку время эпохи по определению считается в UTC, но (см. выше) UTC стандартизировали только в 1972 году. Ну, мы поступим точно так же, как Unix поступает с секундами координации, и притворимся, что это нас не волнует.
Отобразить произвольную дату при помощи команды date(1) довольно легко. Достаточно просто передать дату в формате CCyymmddHHMM.SS . Если только вы не работаете в Linux, где date(1) GNU хочет использовать, наверное, самый выбешивающий формат ( MMDDhhmmCCYY.ss ). Зачем вставлять год между минутами и секундами?
Однако использование любого из этих форматов всё равно бесполезно для наших целей, потому что в определённый момент нам нужно будет выйти за пределы годов из четырёх цифр, поэтому давайте укажем непосредственно секунды после эпохи (» -r » для date(1) в BSD, » —date @ » для date(1) в GNU).
Отобразить даты в момент эпохи или рядом с ней довольно просто:
NetBSD / FreeBSD / macOS: $ date -r 0 Thu Jan 1 00:00:00 UTC 1970 $ date -r -1 Wed Dec 31 23:59:59 UTC 1969 $ date -r 1 Thu Jan 1 00:00:01 UTC 1970
Linux: $ date --date @0 Thu Jan 1 12:00:00 AM UTC 1970 $ date --date @-1 Wed Dec 31 11:59:59 PM UTC 1969 $ date --date @1 Thu Jan 1 12:00:01 AM UTC 1970
OmniOS (с использованием даты GNU) $ date -r 0 January 1, 1970 at 12:00:00 AM UTC $ date -r -1 December 31, 1969 at 11:59:59 PM UTC $ date -r 1 January 1, 1970 at 12:00:01 AM UTC
( date(1) GNU, использующая AM/PM вместо 24 часов, раздражает, ну да ладно.)
Давайте посмотрим, что произойдёт, если мы попробуем проверить 32-битный time_t . Как говорилось выше, проблема 2038 года возникнет в 2147483648 / -2147483649 эпохи:
netbsd$ date -r 2147483647 Tue Jan 19 03:14:07 UTC 2038 netbsd$ date -r 2147483648 Tue Jan 19 03:14:08 UTC 2038 netbsd$ date -r -2147483648 Fri Dec 13 20:45:52 UTC 1901 netbsd$ date -r -2147483649 Fri Dec 13 20:45:51 UTC 1901
linux$ date --date @2147483647 Tue Jan 19 03:14:07 AM UTC 2038 linux$ date --date @2147483648 Tue Jan 19 03:14:08 AM UTC 2038 linux$ date --date @-2147483648 Fri Dec 13 08:45:52 PM UTC 1901 linux$ date --date @-2147483649 Fri Dec 13 08:45:51 PM UTC 1901
omnios$ date -r -2147483648 December 13, 1901 at 08:45:52 PM UTC omnios$ date -r -2147483649 date: failed to parse -r argument: -2147483649 omnios$ date -r 2147483647 January 19, 2038 at 03:14:07 AM UTC omnios$ date -r 2147483648 date: failed to parse -r argument: 2147483648
О, постойте-ка. Похоже, у OmniOS возникают проблемы с датами эпохи после 2^31. Интересно, что произойдёт, если мы не только отобразим дату, но и установим её? Давайте в цикле установим дату и выведем её:
omnios$ for s in 5 6 7 8; do sudo date -u 011903142038.0$s; date; done January 19, 2038 at 03:14:05 AM UTC January 19, 2038 at 03:14:05 AM UTC January 19, 2038 at 03:14:06 AM UTC January 19, 2038 at 03:14:06 AM UTC January 19, 2038 at 03:14:07 AM UTC December 13, 1901 at 08:45:52 PM UTC //. ld.so.1: date: fatal: /lib/libc.so.1: Value too large for defined data type Killed omnios$ date ld.so.1: date: fatal: /lib/libc.so.1: Value too large for defined data type Killed omnios$ ls ld.so.1: ls: fatal: /lib/libc.so.1: Value too large for defined data type Killed omnios$ sudo reboot sudo: unknown uid 100 sudo: error initializing audit plugin sudoers_audit omnios$
Замечательно. Обратите внимание, что дата на самом деле оборачивается, но ОС сходит с ума. Но ведь у других систем не должно быть никаких проблем с установкой даты, правильно?
netbsd# date 197001010000; date +%s Thu Jan 1 00:00:00 UTC 1970 0 netbsd# date 196912312359 date: settimeofday: Invalid argument netbsd$
linux$ sudo date -s @0 date: cannot set date: Invalid argument Thu Jan 1 12:00:00 AM UTC 1970 linux$ uptime; sudo date -s @7080 03:34:27 up 1:57, 1 user, load average: 0.04 Thu Jan 1 01:58:00 AM UTC 1970
Вот так, в NetBSD мы не можем установить дату до эпохи, а в Linux (с версии ядра 4.3) мы не можем установить дату до текущего аптайма. settimeofday(2) вернёт EINVAL из-за гарантий, даваемых его » CLOCK_MONOTONIC «, который, согласно POSIX, «представляет количество времени после неуказанной точки в прошлом«:
Все варианты CLOCK_MONOTONIC гарантируют, что время, возвращаемое последовательными вызовами, не будет идти вспять, однако последовательные вызовы могут (в зависимости от архитектуры) возвращать идентичные (неувеличившиеся) значения времени.
С учётом всего этого, похоже, OmniOS вычисляет аптайм на основе времени запуска относительно системной даты, а, например, NetBSD и Linux хранят отдельные счётчики:
omnios$ sudo date -u 010100001970.00 January 1, 1970 at 12:00:00 AM GMT omnios$ uptime 00:01:46 up -49 min(s), 1 user, load average: 0.00, 0.00, 0.02 omnios$ sudo date -u 011803142038.00 January 18, 2038 at 03:14:00 AM GMT omnios$ uptime 03:14:11 up 5567 day(s), 7 min(s), 1 user, load average: 0.24, 0.16, 0.07
Попытка установить дату до эпохи тоже приводит к разным результатам. В NetBSD и Linux это сделать просто не удастся, а в OmniOS будет установлен месяц, день, час, минута и секунда, однако год будет ограничен значением 1970:
omnios$ sudo date -u 020100001969.00 February 1, 1970 at 12:00:00 AM GMT omnios$ date February 1, 1970 at 12:00:01 AM UTC omnios$ sudo date -u 121308451901.52 December 13, 1970 at 08:45:52 AM GMT omnios$ date December 13, 1970 at 08:45:54 AM UTC
Но какую максимальную дату мы можем установить в системах, использующих 64-битный time_t ? Как говорилось выше, можно ожидать, что доступно время до 2^63 — 1 = 9223372036854775807 эпохи. Давайте сначала отобразим дату, а затем попытаемся её установить:
netbsd$ date -r 9223372036854775807 date: 9223372036854775807: localtime: Value too large to be stored in data type netbsd$ date -r 67768036191676799 Wed Dec 31 23:59:59 UTC 2147485547 netbsd$ date -r 67768036191676800 date: 67768036191676800: localtime: Value too large to be stored in data type
linux$ date --date @9223372036854775807 date: time ‘9223372036854775807’ is out of range linux$ date --date @67768036191676799 Wed Dec 31 11:59:59 PM UTC 2147485547 linux$ date --date @67768036191676800 date: time ‘67768036191676800’ is out of range linux$
freebsd$ date -r 9223372036854775807 date: invalid time freebsd$ date -r 67768036191676799 date: invalid time freebsd$ date -r 67767976233532799 Tue Dec 31 23:59:59 UTC 2147483647 freebsd$ date -r 67767976233532800 date: invalid time
Это интересно. Несмотря на то, что нам обещали 64-битный time_t , мы не можем установить время на 9223372036854775807 . Похоже, максимальное значение равно 67768036191676799 в 2147485547 году. Хотя поначалу это значение кажется произвольным, можно заметить, что 2147485547 — это 2^31 — 1 , и внезапно всё обретает смысл: даже несмотря на то, что time_t является 64-битным, tm_year структуры struct tm всё равно остаётся 32-битным, а потому максимальным значением, которое он может задать, является последняя секунда 2147485547 года.
А как дела в FreeBSD? Почему в ней время 67768036191676799 эпохи является недопустимым, а 67767976233532799 эпохи соответствует тому, что на других платформах является 67768036191676799 ? Если провести вычисления, то можно заметить, что разница между этими двумя моментами времени эпохи равна 1900 годам, то есть, очевидно, FreeBSD основывает свой tm_year не на 1900 годе (как заявляется struct tm в ), а на 0 годе? Так как я не смог с этим разобраться, то отправил баг-репорт.
Если мы попытаемся установить дату, то поначалу заметим, что при использовании date(1) NetBSD невозможно установить дату выше 9999 года (ещё один баг-репорт), но забавно, что на самом деле это не важно, поскольку мы всё равно не можем добраться выше 4147 года:
netbsd# date 414708200732.17 date: settimeofday: Invalid argument netbsd# date 414708200732.16; date +%s Sun Aug 20 07:32:16 UTC 4147 68719476736
Так получилось потому, что в NetBSD есть жёстко прописанное ограничение в 2^36 = 68719476736 для значения tv_sec , которое принимается при установке времени, потому что бОльшие значения вызывают недовольство KUBSAN (код):
/* * Установка завышенного значения времени * приводит к недопустимому поведению системы. */ if (ts->tv_sec < 0 || ts->tv_sec > (1LL
В Linux используется другой практический максимум даты, установленный на 2232 год:
linux$ sudo date -s @8277292036 date: cannot set date: Invalid argument Wed Apr 18 11:47:16 PM UTC 2232 linux$ sudo date -s '@8277292035' Wed Apr 18 11:47:15 PM UTC 2232 linux$ sleep 10; date +%s 8277292045 linux$ sudo date -s @$(date +%s) date: cannot set date: Invalid argument Wed Apr 18 11:47:25 PM UTC 2232
Причина этого ограничения, найденная в исходном коде, заключается в том, что оно может использовать 30-летний аптайм до оборачивания счётчика:
#define NSEC_PER_SEC 1000000000L #define KTIME_MAX ((s64)~((u64)1
Это означает, что в Linux знаковое 64-битное максимальное значение времени ( 2^63 - 1 = 9223372036854775807 ) не обозначает секунды после эпохи, а подсчитывает наносекунды после эпохи, поэтому теоретическая максимальная дата Linux ( KTIME_SEC_MAX ) снижается до всего лишь 9223372036 секунд эпохи, или даты 2262-04-23T11:47:16, что очень далеко от «22 приблизительных возрастов Вселенной», и ближе к тому, чтобы стать реальной проблемой.
Проверяя, какое значение FreeBSD позволяет установить для часов, я выяснил, что в двух последних релизах это значение различается, но оба релиза имели неприятную проблему, приводящую к спонтанной перезагрузке системы:
freebsd# date -u -f "%s" 49282253052249598 Fri Dec 31 23:59:58 UTC 1561694399 49282253052249598 freebsd# sleep 1; date; date +%s Fri Dec 31 23:59:59 UTC 1561694399 49282253052249599 freebsd# sleep 1; date; date +%s Sat Jan 1 00:00:00 UTC 1561694400 49282253052249600 [ system reboots ]
Примечание: изначально я могу установить дате значение больше 49282253052249598 , но спустя примерно три секунды система перезагружается. Если задать дату на одну секунду меньше, то есть 49282253052249597 , то система не перезагружается, даже когда системное время уходит дальше следующего значения. Разве компьютеры — это не чудесно?
О, и ещё кое-что.
Всем нам нравится, что macOS — это UNIX; она является одной из всего шести зарегистрированных на данный момент систем (остальные — это AIX, EulerOS (коммерческий дистрибутив Linux, созданный Huawei), HP-UX, Xinuos (ранее UnixWare, создан старыми AT&T Unix System Laboratories + Novell, SCO,
Caldera и UnXis) и z/OS). Однако фреймворк Core Foundation компании Apple не использует эпоху Unix как основу своего времени. В качестве его даты отсчёта используется 2001-01-01T00:00:00 GMT:
Все варианты CLOCK_MONOTONIC гарантируют, что время, возвращаемое Core
Foundation, измеряет время в секундах. В качестве базового типа данных используется CFTimeInterval, измеряющий разность в секундах между двумя моментами времени. Фиксированные моменты времени, или даты определяются типом данных CFAbsoluteTime, измеряющим интервал времени между конкретной датой и абсолютной датой отсчёта Jan 1 2001 00:00:00 GMT.
То есть если вы захотите преобразовать эти метки времени в эпоху Unix, нужно будет прибавить 978307200 .
Как я и сказал, время — иллюзия, а время Unix — иллюзия вдвойне. И хотя вас может и не беспокоить проблема 2038 года (наверно, только если вы не пользуетесь OmniOS), возможно, мне удалось показать, что внутри может таиться множество других сюрпризов. А ведь мы ещё не касались безумия, творящегося с часовыми поясами и летним временем…
- Системное администрирование
- *nix
- Разработка под Linux
- История IT
UNIX timestamp
UNIX-время или POSIX-время (англ. Unix time ) — способ кодирования времени, принятый в POSIX-совместимых операционных системах.
Моментом начала отсчёта считается полночь (по UTC) с 31 декабря 1969 года на 1 января 1970, время с этого момента называют «эрой UNIX» (англ. Unix Epoch ).
Время UNIX согласуется с UTC, в частности, при объявлении високосных секунд UTC соответствующие номера секунд повторяются.
Способ хранения времени в виде количества секунд очень удобно использовать при сравнении дат (с точностью до секунды), а также для хранения дат: при необходимости их можно преобразовать в любой удобочитаемый формат. Дата и время в этом формате также занимают очень мало места (4 или 8 байтов, в зависимости от размера машинного слова), поэтому его разумно использовать для хранения больших объёмов дат. Недостатки в производительности могут проявиться при очень частом обращении к элементам даты, вроде номера месяца и т. п. Но в большинстве случаев эффективнее хранить время в виде одной величины, а не набора полей.
Чтобы узнать текущее UNIX-время в большинстве UNIX-подобных систем, можно использовать команду date +%s .
13 февраля 2009 года в 23:31:30 по UTC (02:31:30 14 февраля по MSK) значение UNIX-времени достигло 1234567890 секунд.
19 января 2038 года в 03:14:08 по всемирному времени значение переменной типа time_t , отсчитывающей число секунд, прошедших с 1 января 1970 года, достигнет 2 31 , что может привести к ошибочной интерпретации этого числа как отрицательного. Возможное решение данной проблемы состоит в использовании не 32-битной, а 64-битной переменной для хранения времени, чего хватит ещё на 300 миллиардов лет.
См. также
Ссылки
Wikimedia Foundation . 2010 .
Полезное
Смотреть что такое "UNIX timestamp" в других словарях:
- Unix-Timestamp — Die Unixzeit ist eine einfache Zeitdefinition, die 1969 für das Betriebssystem Unix entwickelt und als POSIX Standard festgelegt wurde. In den ersten Tagen von Unix wurde die Definition mehrfach geändert. Seit mehreren Jahrzehnten ist sie jedoch… … Deutsch Wikipedia
- Unix timestamp — Эта статья о формате кодирования времени; об утилите см.: time (Unix). UNIX время или POSIX время (англ. Unix time) способ кодирования времени, принятый в POSIX совместимых операционных системах. Моментом начала отсчёта считается полночь (по… … Википедия
- Unix time — Unix time, or POSIX time, is a system for describing points in time, defined as the number of seconds elapsed since midnight Coordinated Universal Time (UTC) of January 1 1970, not counting leap seconds. It is widely used not only on Unix like… … Wikipedia
- Timestamp — es una secuencia de caracteres, que denotan la hora y fecha (o alguna de ellas) en la cual ocurrió determinado evento. Esta información es comúnmente presentada en un formato consistente, lo que permite la fácil comparación entre dos diferentes… … Wikipedia Español
- Timestamp — Ein Zeitstempel (engl.: timestamp) ist ein Wert in einem definierten Format, der einem Ereignis (beispielsweise dem Senden oder Empfangen einer Nachricht, der Modifikation von Daten u. a.) einen Zeitpunkt zuordnet. Der Zweck eines Zeitstempels… … Deutsch Wikipedia
- Timestamp (informatique) — Timestamp désigne en informatique un compteur numérique servant de référence temporelle et représente le nombre de secondes écoulées depuis un instant de référence. Description C est un mot composé venant de l anglais « time » (heure)… … Wikipédia en Français
- Timestamp — A timestamp is a sequence of characters, denoting the date and/or time at which a certain event occurred. This data is usually presented in a consistent format, allowing for easy comparison of two different records and tracking progress over… … Wikipedia
- Unix-Epoche — Die Unixzeit ist eine einfache Zeitdefinition, die 1969 für das Betriebssystem Unix entwickelt und als POSIX Standard festgelegt wurde. In den ersten Tagen von Unix wurde die Definition mehrfach geändert. Seit mehreren Jahrzehnten ist sie jedoch… … Deutsch Wikipedia
- Unix-Zeit — Die Unixzeit ist eine einfache Zeitdefinition, die 1969 für das Betriebssystem Unix entwickelt und als POSIX Standard festgelegt wurde. In den ersten Tagen von Unix wurde die Definition mehrfach geändert. Seit mehreren Jahrzehnten ist sie jedoch… … Deutsch Wikipedia
- UNIX-время — Эта статья о формате кодирования времени; об утилите см.: time (Unix). UNIX время (англ. Unix time) или POSIX время система описания моментов во времени, принятая в UNIX и других POSIX совместимых операционных системах. Определяется… … Википедия
- Обратная связь: Техподдержка, Реклама на сайте
- Путешествия
Экспорт словарей на сайты, сделанные на PHP,
WordPress, MODx.
- Пометить текст и поделитьсяИскать в этом же словареИскать синонимы
- Искать во всех словарях
- Искать в переводах
- Искать в ИнтернетеИскать в этой же категории
Заблуждения программистов о Unix-времени
Вчера Дэнни поинтересовался любопытными фактами о Unix-времени, а я вспомнил, что иногда оно работает совершенно неинтуитивно.
Вот эти три факта кажутся в высшей степени разумными и логичными, не так ли?
- Время Unix — это количество секунд с 1 января 1970 года 00:00:00 UTC.
- Если подождать ровно одну секунду, то время Unix изменится ровно на одну секунду.
- Время Unix никогда не двигается назад.
Настольные часы 1770-х годов. Собрано Джоном Леру. Из коллекции Wellcome. Опубликовано под лицензией CC BY
У всех трёх заблуждений одна причина: високосные секунды. Если вы не знакомы с дополнительными секундами, вот краткая справка:
Время UTC определяется двумя факторами:
- Международное атомное время: усреднённые показания сотен атомных часов по всему миру. Мы можем измерить секунду по электромагнитным свойствам атома, и это самое точное измерение времени, известное науке.
- Всемирное время, основанное на вращении Земли вокруг собственной оси. Один полный оборот — одни сутки.
Когда два времени выпадают из синхрона, в UTC добавляется или удаляется секунда, чтобы вернуть синхронизацию. С 1972 года служба IERS (которая управляет этим делом) добавила 27 дополнительных секунд. В результате получилось 27 суток UTC продолжительностью в 86 401 секунду. Теоретически возможно появление суток продолжительностью 86 399 секунд (минус одна). Оба варианта противоречат фундаментальному предположению о Unix-времени.
Время Unix предполагает, что каждый день длится ровно 86 400 секунд (60 × 60 × 24 = 86 400), без всяких дополнительных секунд. Если происходит такой скачок, то время Unix либо перепрыгивает через секунду, либо отсчитывая две секунды за одну. По состоянию на 2019 год в нём отсутствует 27 високосных секунд.
Так что наши заблуждения нужно дополнить следующим образом:
- Время Unix — это количество секунд с 1 января 1970 00:00:00 UTC минус високосные секунды.
- Если подождать ровно одну секунду, время Unix изменится ровно на одну секунду, если не была удалена дополнительная секунда.
До сих пор на практике секунды никогда не удалялись (и замедление вращения Земли означает, что это маловероятно), но если бы это когда-либо произошло, это означало бы, что день UTC стал на одну секунду короче. В этом случае последняя секунда UTC (23:59:59) отбрасывается.
В каждых сутках Unix одинаковое количество секунд, поэтому последняя Unix-секунда укороченного дня не будет соответствовать никакому времени UTC. Вот как это выглядит, в интервалах по четверти секунды:
Это уже 27 раз произошло на практике. По окончании суток UTC добавляют дополнительную секунду 23:59:60. В сутках Unix одинаковое количество секунд, поэтому он не может добавить дополнительную секунду — вместо этого приходится повторять метки времени Unix для последней секунды. Вот как это выглядит, в интервалах по четверти секунды:
Время — очень странная штука.