Время Unix [a] — это представление даты и времени, широко используемое в вычислительной технике . Оно измеряет время по количеству невисокосных секунд , прошедших с 00:00:00 UTC 1 января 1970 года, эпохи Unix . Например, в полночь 1 января 2010 года время Unix было 1262304000.
Время Unix возникло как системное время операционных систем Unix . Оно стало широко использоваться в других компьютерных операционных системах , файловых системах , языках программирования и базах данных . В современных вычислениях значения иногда хранятся с более высокой степенью детализации , например, микросекундами или наносекундами .
В настоящее время время Unix определяется как количество секунд без учета високосных, прошедших с 00:00:00 UTC в четверг, 1 января 1970 года, что называется эпохой Unix . [3] Время Unix обычно кодируется как целое число со знаком .
Время Unix0 — это точно полночь UTC 1 января 1970 года, при этом время Unix увеличивается на 1 за каждую невисокосную секунду после этого. Например, 00:00:00 UTC 1 января 1971 года представлено в Unix-времени как31 536 000. Отрицательные значения в системах, которые их поддерживают, указывают время до эпохи Unix, причем значение уменьшается на 1 за каждую невисокосную секунду до эпохи. Например, 00:00:00 UTC 1 января 1969 года представлено в Unix-времени как−31 536 000. Каждый день в Unix-времени состоит ровно из86 400 секунд.
Время Unix иногда называют временем эпохи . Это может ввести в заблуждение, поскольку время Unix — не единственная система времени, основанная на эпохе, а эпоха Unix — не единственная эпоха, используемая другими системами времени. [5]
Время Unix отличается как от Всемирного координированного времени (UTC), так и от Международного атомного времени (TAI) в обработке дополнительных секунд . UTC включает дополнительные секунды, которые корректируют расхождение между точным временем, измеренным атомными часами , и солнечным временем , связанным с положением Земли по отношению к Солнцу. Международное атомное время (TAI), в котором каждый день точно86 400 секунд, игнорирует солнечное время и постепенно теряет синхронизацию с вращением Земли со скоростью примерно одну секунду в год. В Unix-времени каждый день содержит ровно86 400 секунд. Каждая високосная секунда использует временную метку секунды, которая непосредственно предшествует или следует за ней. [3]
В обычный день UTC, который длится86 400 секунд, число времени Unix непрерывно меняется в полночь. Например, в конце дня, использованного в примерах выше, представления времени прогрессируют следующим образом:
Когда появляется дополнительная секунда , день UTC не совпадает с днем86 400 секунд и номер времени Unix (который всегда увеличивается ровно на86 400 каждый день) испытывает разрыв . Високосные секунды могут быть положительными или отрицательными. Отрицательная високосная секунда никогда не объявлялась, но если бы она была, то в конце дня с отрицательной високосной секундой число времени Unix подскочило бы на 1 к началу следующего дня. Во время положительной високосной секунды в конце дня, что происходит в среднем примерно каждые полтора года, число времени Unix непрерывно увеличивается к следующему дню в течение високосной секунды, а затем в конце високосной секунды подскочило бы на 1 (возвращаясь к началу следующего дня). Например, вот что произошло в строго соответствующих POSIX.1 системах в конце 1998 года:
Числа времени Unix повторяются в секунде, следующей сразу за положительной дополнительной секундой. Число времени UnixТаким образом, 1 483 228 800 неоднозначно: оно может относиться либо к началу секунды координации (2016-12-31 23:59:60), либо к ее концу, на одну секунду позже (2017-01-01 00:00:00). В теоретическом случае, когда возникает отрицательная секунда координации, никакой неоднозначности не возникает, но вместо этого существует диапазон чисел времени Unix, которые вообще не относятся ни к какой точке времени UTC.
Часы Unix часто реализуются с другим типом обработки положительной секунды координации, связанным с сетевым протоколом времени (NTP). Это приводит к системе, которая не соответствует стандарту POSIX. Подробности см. в разделе ниже, посвященном NTP.
При работе с периодами, которые не охватывают високосную секунду UTC, разница между двумя числами времени Unix равна продолжительности периода в секундах между соответствующими точками во времени. Это распространенный вычислительный метод. Однако, когда возникают високосные секунды, такие вычисления дают неверный ответ. В приложениях, где требуется такой уровень точности, необходимо сверяться с таблицей високосных секунд при работе со временем Unix, и часто предпочтительнее использовать другую кодировку времени, которая не страдает от этой проблемы.
Число времени Unix легко преобразуется обратно во время UTC путем взятия частного и модуля числа времени Unix по модулю86 400 . Частное — это количество дней с начала эпохи, а модуль — это количество секунд с полуночи UTC в этот день. Если дано число времени Unix, которое неоднозначно из-за положительной секунды координации, этот алгоритм интерпретирует его как время сразу после полуночи. Он никогда не генерирует время, которое находится в течение секунды координации. Если дано число времени Unix, которое недействительно из-за отрицательной секунды координации, он генерирует столь же недействительное время UTC. Если эти условия существенны, необходимо обратиться к таблице секунд координации, чтобы обнаружить их.
Обычно часы Unix в стиле Миллса реализуются с обработкой секунды координации, не синхронной с изменением номера времени Unix. Номер времени сначала уменьшается там, где должен был произойти скачок, а затем он переходит на правильное время через 1 секунду после скачка. Это упрощает реализацию и описано в статье Миллса. [6] Вот что происходит при положительной секунде координации:
Это можно правильно расшифровать, обратив внимание на переменную состояния секунды високосного периода, которая однозначно указывает, был ли уже выполнен скачок. Изменение переменной состояния синхронно с скачком.
Аналогичная ситуация возникает с отрицательной секундой координации, когда пропущенная секунда немного запаздывает. Очень короткое время система показывает номинально невозможное число времени, но это можно обнаружить по состоянию TIME_DEL и исправить.
В этом типе системы число времени Unix нарушает POSIX вокруг обоих типов секунды координации. Сбор переменной состояния секунды координации вместе с числом времени позволяет выполнить однозначное декодирование, поэтому при желании можно сгенерировать правильное число времени POSIX или сохранить полное время UTC в более подходящем формате.
Логика декодирования, необходимая для работы с этим стилем часов Unix, также будет правильно декодировать гипотетические часы, соответствующие POSIX, используя тот же интерфейс. Это будет достигнуто путем указания состояния TIME_INS в течение всей вставленной секунды координации, а затем указания TIME_WAIT в течение всей следующей секунды при повторении подсчета секунд. Это требует синхронной обработки секунд координации. Это, вероятно, лучший способ выразить время UTC в форме часов Unix через интерфейс Unix, когда базовые часы принципиально не беспокоятся о секундах координации.
Другой, гораздо более редкий, несоответствующий требованиям вариант ведения времени в Unix подразумевает увеличение значения для всех секунд, включая високосные секунды; [7] некоторые системы Linux настроены таким образом. [8] Время, сохраняемое таким образом, иногда называют «TAI» (хотя временные метки могут быть преобразованы в UTC, если значение соответствует времени, когда известна разница между TAI и UTC), в отличие от «UTC» (хотя не все значения времени UTC имеют уникальную ссылку в системах, которые не учитывают високосные секунды). [8]
Поскольку в TAI нет дополнительных секунд, а каждый день TAI длится ровно 86400 секунд, эта кодировка на самом деле является чистым линейным подсчетом секунд, прошедших с 1970-01-01T00:00:10 TAI. Это значительно упрощает арифметику временных интервалов. Значения времени из этих систем не страдают от неоднозначности, которая свойственна строго соответствующим системам POSIX или системам, управляемым NTP.
В этих системах необходимо обратиться к таблице дополнительных секунд для правильного преобразования между UTC и представлением псевдо-Unix-времени. Это напоминает способ, которым таблицы часовых поясов должны быть проверены для преобразования в гражданское время и обратно ; база данных часовых поясов IANA включает информацию о дополнительных секундах, и пример кода, доступный из того же источника, использует эту информацию для преобразования между временными метками на основе TAI и местным временем. Преобразование также сталкивается с проблемами определения до начала 1972 года текущей формы UTC (см. раздел Основа UTC ниже).
Эта система, несмотря на внешнее сходство, не является временем Unix. Она кодирует время со значениями, которые отличаются на несколько секунд от значений времени POSIX. Версия этой системы, в которой эпоха была 1970-01-01T00:00:00 TAI вместо 1970-01-01T00:00:10 TAI, была предложена для включения в ISO C's time.h
, но в 2011 году была принята только часть UTC. [9] Однако A tai_clock
существует в C++20.
Число времени Unix может быть представлено в любой форме, способной представлять числа. В некоторых приложениях число просто представлено текстуально как строка десятичных цифр, что вызывает лишь незначительные дополнительные проблемы. Однако некоторые двоичные представления времени Unix особенно значимы.
Тип данных Unix time_t
, представляющий момент времени, на многих платформах представляет собой знаковое целое число , традиционно 32- битное (но см. ниже), напрямую кодирующее число времени Unix, как описано в предыдущем разделе. Знаковое 32-битное значение охватывает около 68 лет до и после эпохи 1970-01-01. Минимальная представимая дата — пятница 1901-12-13, а максимальная представимая дата — вторник 2038-01-19. Через секунду после 2038-01-19T03:14:07Z это представление переполнится, что известно как проблема 2038 года .
В некоторых новых операционных системах time_t
был расширен до 64 бит. Это расширяет время, представляемое примерно до 292,3 миллиарда лет в обоих направлениях, что более чем в двадцать раз превышает нынешний возраст Вселенной .
Первоначально существовали некоторые разногласия по поводу того, должен ли Unix time_t
быть знаковым или беззнаковым. Если беззнаковый, его диапазон в будущем будет удвоен, откладывая 32-битное переполнение (на 68 лет). Однако тогда он не сможет представлять время до эпохи. Консенсус заключается в том, чтобы time_t
быть знаковым, и это обычная практика. Платформа разработки программного обеспечения для версии 6 операционной системы QNX имеет беззнаковый 32-битный time_t
, хотя более старые выпуски использовали знаковый тип.
Спецификации POSIX и Open Group Unix включают стандартную библиотеку C , которая включает типы времени и функции, определенные в заголовочном файле. Стандарт ISO C утверждает, что это должен быть арифметический тип, но не предписывает какой-либо конкретный тип или кодировку для него. POSIX требует, чтобы это был целочисленный тип, но не предписывает, чтобы он был знаковым или беззнаковым.<time.h>
time_t
time_t
Unix не имеет традиции прямого представления нецелых чисел времени Unix в виде двоичных дробей. Вместо этого время с точностью до секунды представляется с использованием составных типов данных , состоящих из двух целых чисел, первое из которых — a time_t
(целая часть времени Unix), а второе — дробная часть числа времени в миллионных (в struct timeval
) или миллиардных (в struct timespec
). [10] [11] Эти структуры предоставляют формат данных с фиксированной точкой на основе десятичной дроби , который полезен для некоторых приложений и тривиален для преобразования для других.
Текущая форма UTC с дополнительными секундами определена только с 1 января 1972 года. До этого, с 1 января 1961 года, существовала более старая форма UTC, в которой не только время от времени были временные шаги, которые были нецелыми числами секунд, но и секунда UTC была немного длиннее секунды SI и периодически изменялась, чтобы непрерывно приближаться к вращению Земли. До 1961 года не было UTC, а до 1958 года не было широко распространенного атомного хронометража ; в эти эпохи использовалось некоторое приближение GMT (основанное непосредственно на вращении Земли) вместо атомной шкалы времени. [ необходима цитата ]
Точное определение времени Unix как кодировки UTC не вызывает споров только применительно к современной форме UTC. Эпоха Unix, предшествовавшая началу этой формы UTC, не влияет на ее использование в эту эпоху: количество дней с 1 января 1970 года (эпоха Unix) по 1 января 1972 года (начало UTC) не вызывает вопросов, и количество дней — это все, что имеет значение для времени Unix.
Значение значений времени Unix ниже+63 072 000 (т. е. до 1 января 1972 г.) точно не определено. Основой такого времени Unix лучше всего считать неопределенное приближение UTC. Компьютеры той эпохи редко имели часы, установленные достаточно точно, чтобы в любом случае предоставлять значимые метки времени с точностью до секунды. Время Unix не является подходящим способом представления времени до 1972 г. в приложениях, требующих точности до секунды; такие приложения должны, по крайней мере, определять, какую форму UT или GMT они используют.
С 2009 года [обновлять]рассматривается возможность прекращения использования дополнительных секунд в гражданском времени. [12] Вероятным способом реализации этого изменения является определение новой шкалы времени, называемой Международным временем [ требуется ссылка ] , которая изначально соответствует UTC, но впоследствии не имеет дополнительных секунд, таким образом оставаясь на постоянном смещении относительно TAI. Если это произойдет, то, вероятно, время Unix будет перспективно определяться в терминах этой новой шкалы времени, а не UTC. Неопределенность относительно того, произойдет ли это, делает перспективное время Unix не менее предсказуемым, чем оно уже есть: если бы UTC просто не имело дополнительных дополнительных секунд, результат был бы тем же.
Самые ранние версии времени Unix имели 32-битное целое число, увеличивающееся с частотой 60 Гц , что соответствовало частоте системных часов на оборудовании ранних систем Unix. Метки времени, сохраненные таким образом, могли представлять только диапазон чуть более двух с четвертью лет. Эпоха, от которой отсчитывался счет, была изменена с выпусками Unix, чтобы предотвратить переполнение, и в начале разработки Unix в качестве эпох использовались полночь 1 января 1971 года и 1 января 1972 года. Ранние определения времени Unix также не содержали часовых поясов. [13] [14]
Текущая эпоха 1 января 1970 00:00:00 UTC была выбрана инженерами Unix произвольно, поскольку считалась удобной для работы. Точность была изменена на подсчет в секундах, чтобы избежать кратковременного переполнения. [1]
Когда был написан POSIX.1 , встал вопрос о том, как точно определить time_t
в условиях високосных секунд. Комитет POSIX рассматривал вопрос о том, должно ли время Unix оставаться, как предполагалось, линейным подсчетом секунд с начала эпохи за счет сложности преобразований с гражданским временем или представлением гражданского времени за счет непоследовательности вокруг високосных секунд. Компьютерные часы той эпохи не были достаточно точно установлены, чтобы сформировать прецедент в ту или иную сторону.
Комитет POSIX был склонен к аргументам против сложности библиотечных функций [ требуется ссылка ] и твердо определил время Unix простым способом в терминах элементов времени UTC. Это определение было настолько простым, что оно даже не охватывало все правило високосного года григорианского календаря и делало 2100 год високосным.
В издании POSIX.1 2001 года было исправлено ошибочное правило високосного года в определении времени Unix, но сохранено основное определение времени Unix как кодировки UTC, а не линейной шкалы времени. С середины 1990-х годов компьютерные часы обычно устанавливаются с достаточной точностью, чтобы это имело значение, и чаще всего они устанавливаются с использованием определения времени Unix на основе UTC. Это привело к значительной сложности в реализациях Unix и в сетевом протоколе времени для выполнения шагов в числе времени Unix всякий раз, когда возникают високосные секунды. [ необходима цитата ]
Время Unix широко применяется в вычислительной технике за пределами своего первоначального применения в качестве системного времени для Unix . Время Unix доступно практически во всех API системного программирования, включая те, которые предоставляются как операционными системами на основе Unix, так и не-Unix . Почти все современные языки программирования предоставляют API для работы со временем Unix или преобразования его в другую структуру данных. Время Unix также используется как механизм для хранения временных меток в ряде файловых систем , форматов файлов и баз данных .
Стандартная библиотека C использует время Unix для всех функций даты и времени, а время Unix иногда называют time_t, именем типа данных , используемого для временных меток в C и C++ . Функции времени Unix в C определены как API системного времени в спецификации POSIX . [15] Стандартная библиотека C широко используется во всех современных настольных операционных системах, включая Microsoft Windows и Unix-подобные системы, такие как macOS и Linux , где она является стандартным интерфейсом программирования. [16] [17] [18]
iOS предоставляет API Swift, который по умолчанию использует эпоху 1 января 2001 года, но может также использоваться с временными метками Unix. [19] Android использует время Unix вместе с часовым поясом для своего API системного времени. [20]
Windows не использует время Unix для внутреннего хранения времени, но использует его в системных API, которые предоставляются в C++ и реализуют спецификацию стандартной библиотеки C. [16] Время Unix используется в формате PE для исполняемых файлов Windows. [21]
Время Unix обычно доступно в основных языках программирования и широко используется в программировании настольных, мобильных и веб-приложений. Java предоставляет объект Instant, который содержит временную метку Unix как в секундах, так и в наносекундах. [22] Python предоставляет библиотеку времени, которая использует время Unix. [23] JavaScript предоставляет библиотеку Date, которая предоставляет и хранит временные метки в миллисекундах с эпохи Unix и реализована во всех современных настольных и мобильных веб-браузерах , а также в серверных средах JavaScript , таких как Node.js. [24]
Файловые системы, разработанные для использования с операционными системами на базе Unix, как правило, используют время Unix. APFS , файловая система, используемая по умолчанию на всех устройствах Apple, и ext4 , которая широко используется на устройствах Linux и Android, используют время Unix в наносекундах для временных меток файлов. [25] [26] Несколько форматов архивных файлов могут хранить временные метки в формате времени Unix, включая RAR и tar . [27] [28] Время Unix также обычно используется для хранения временных меток в базах данных, включая MySQL и PostgreSQL . [29] [30]
Время Unix было разработано для кодирования календарных дат и времени в компактной форме, предназначенной для внутреннего использования компьютерами. Оно не предназначено для легкого чтения людьми или для хранения значений, зависящих от часового пояса. Оно также ограничено по умолчанию представлением времени в секундах, что делает его непригодным для использования, когда требуется более точное измерение времени, например, при измерении времени выполнения программ. [31]
Время Unix по своей конструкции не требует определенного размера для хранения, но большинство распространенных реализаций времени Unix используют знаковое целое число того же размера, что и размер слова базового оборудования. Поскольку большинство современных компьютеров являются 32- или 64-разрядными , а большое количество программ по-прежнему написано в режиме совместимости с 32-разрядной архитектурой, это означает, что многие программы, использующие время Unix, используют поля знаковых 32-разрядных целых чисел. Максимальное значение знакового 32-разрядного целого числа равно 2 31 − 1 , а минимальное значение равно −2 31 , что делает невозможным представление дат до 13 декабря 1901 года (в 20:45:52 UTC) или после 19 января 2038 года (в 03:14:07 UTC). Раннее отключение может оказать влияние на базы данных, в которых хранится историческая информация; В некоторых базах данных, где для временных меток используется 32-битное время Unix, может потребоваться хранить время в поле другой формы, например, в строке, для представления дат до 1901 года. Позднее отсечение известно как проблема 2038 года и может вызвать проблемы по мере приближения даты, поскольку даты после отсечки 2038 года будут возвращаться к началу представляемого диапазона в 1901 году. [31] : 60
Ограничения диапазона дат не являются проблемой при 64-битном представлении времени Unix, поскольку эффективный диапазон дат, представляемых временем Unix, сохраненным в виде 64-битного целого числа со знаком, составляет более 584 миллиардов лет или 292 миллиарда лет в любом направлении от эпохи 1970 года. [31] : 60-61 [32]
Время Unix — не единственный стандарт времени, отсчитывающий время от эпохи. В Windows этот FILETIME
тип хранит время как количество 100-наносекундных интервалов, прошедших с 0:00 GMT 1 января 1601 года. [33] Время эпохи Windows используется для хранения временных меток для файлов [34] и в таких протоколах, как Active Directory Time Service [35] и Server Message Block .
Сетевой протокол времени, используемый для координации времени между компьютерами, использует эпоху 1 января 1900 года, отсчитываемую беззнаковым 32-битным целым числом для секунд и другим беззнаковым 32-битным целым числом для дробных секунд, которые переходят каждые 2,32 секунды (примерно раз в 136 лет). [36]
Многие приложения и языки программирования предоставляют методы для хранения времени с явным указанием часового пояса. [37] Существует также ряд стандартов формата времени, которые могут читать как люди, так и компьютеры, например ISO 8601 .
Энтузиасты Unix имеют историю проведения "time_t parties" (произносится как "time tea parties "), чтобы отпраздновать значимые значения числа времени Unix. [38] [39] Это прямой аналог празднования Нового года , которое происходит при смене года во многих календарях. По мере распространения использования времени Unix распространилась и практика празднования его вех. Обычно отмечаются значения времени, которые являются круглыми числами в десятичной системе счисления , следуя соглашению Unix о представлении time_t
значений в десятичной системе счисления. Среди некоторых групп также отмечаются круглые двоичные числа, например, +2 30 , которое произошло в 13:37:04 UTC в субботу, 10 января 2004 года. [ необходима цитата ]
События, которые они отмечают, обычно описываются как « N секунд с начала эпохи Unix», но это неточно; как обсуждалось выше, из-за обработки дополнительных секунд в Unix-времени количество секунд, прошедших с начала эпохи Unix, немного больше, чем число секунд Unix-времени для времени, наступившего позже эпохи.
Роман Вернора Винджа «Глубина в небе » описывает космическую торговую цивилизацию, существующую тысячи лет в будущем, которая все еще использует эпоху Unix. « Программист-археолог », ответственный за поиск и поддержание пригодного к использованию кода в зрелых компьютерных системах, сначала полагает, что эпоха относится ко времени, когда человек впервые ступил на Луну , но затем понимает, что это «нулевая секунда одной из первых компьютерных операционных систем человечества». [47]
и данные tz поддерживают високосные секунды через дополнительную "правильную" конфигурацию, в которой внутренние целочисленные часы time_t компьютера отсчитывают каждую секунду TAI, в отличие от конфигурации по умолчанию "posix", в которой внутренние часы игнорируют високосные секунды. Две конфигурации совпадают для временных меток, начинающихся с 1972-01-01 00:00:00 UTC (time_t 63 072 000), и расходятся для временных меток, начинающихся с time_t 78 796 800, что соответствует первой високосной секунде 1972-06-30 23:59:60 UTC в «правильной» конфигурации и 1972-07-01 00:00:00 UTC в конфигурации «posix».
time
возвращает время с 00:00:00 1 января 1971 г., измеренное в шестидесятых долях секунды.
time
возвращает время с 00:00:00, 1 января 1972 г., измеренное в шестидесятых долях секунды... Время хранится в 32 битах. Это гарантирует кризис каждые 2,26 года.
Проект библиотеки GNU C предоставляет основные библиотеки для системы GNU и систем GNU/Linux, а также многих других систем, использующих Linux в качестве ядра.
Эта временная метка представлена как количество наносекунд с 1 января 1970 года в 0:00 UTC, без учета дополнительных секунд.
Время хранится в формате Unix time_t, если этот флаг [sic] установлен, и в формате Windows FILETIME в противном случае
Атрибуты: год, месяц, день, час, минута, секунда, микросекунда и tzinfo.