Duas camadas de codificação compõem o tempo Unix. A primeira camada codifica um ponto no tempo como um número real escalar que representa o número de segundos que passaram desde 00:00:00 UTC Quinta-feira, 1 de Janeiro de 1970. A segunda camada codifica esse número como uma seqüência de bits ou dígitos decimais.
Como é padrão com UTC, este artigo etiqueta dias usando o calendário gregoriano, e conta os tempos dentro de cada dia em horas, minutos e segundos. Alguns dos exemplos também mostram o Tempo Atômico Internacional (TAI), outro esquema de tempo que usa os mesmos segundos e é exibido no mesmo formato do UTC, mas no qual cada dia tem exatamente 86400 segundos, perdendo gradualmente a sincronização com a rotação da Terra a uma taxa de aproximadamente um segundo por ano.
Tempo de codificação como um númeroEditar
Tempo Unix é um número único assinado que incrementa a cada segundo, o que torna mais fácil para os computadores armazenarem e manipularem do que os sistemas convencionais de data. Programas interpretadores podem então convertê-lo para um formato legível por humanos.
A época Unix é a hora 00:00:00 UTC em 1 de Janeiro de 1970. Há um problema com esta definição, na medida em que o UTC não existia na sua forma atual até 1972; esta questão é discutida abaixo. Para maior brevidade, o restante desta seção usa o formato de data e hora ISO 8601, no qual a época Unix é 1970-01-01T00:00:00Z.
O número de tempo Unix é zero na época Unix, e aumenta em exatamente 86400 por dia desde a época. Assim 2004-09-16T00:00:00Z, 12677 dias após a época, é representado pelo número de tempo Unix 12677 × 86400 = 1095292800. Isto também pode ser estendido para trás a partir da época, usando números negativos; assim 1957-10-04T00:00:00Z, 4472 dias antes da época, é representado pelo número de tempo Unix -4472 × 86400 = -386380800. Isto também se aplica dentro de dias; o número de tempo em qualquer hora do dia é o número de segundos que passou desde a meia-noite que começou naquele dia adicionado ao número de tempo daquela meia-noite.
Porque o tempo Unix é baseado em uma época, e por causa de um mal entendido comum de que a época Unix é a única época (freqüentemente chamada “a época”), o tempo Unix é às vezes referido como tempo Epoch.
Saltar segundosEditar
O esquema acima significa que em um dia UTC normal, que tem uma duração de 86400 segundos, o número de tempo Unix muda de uma maneira contínua através da meia-noite. Por exemplo, no final do dia utilizado nos exemplos acima, as representações de tempo progridem da seguinte forma:
Quando ocorre um salto de segundo, o dia UTC não tem exactamente 86400 segundos e o número de tempo Unix (que aumenta sempre exactamente 86400 a cada dia) experimenta uma descontinuidade. Os segundos bissextos podem ser positivos ou negativos. Nenhum segundo bissexto negativo jamais foi declarado, mas se um fosse, no final de um dia com um segundo bissexto negativo, o número de tempo Unix saltaria 1 para o início do dia seguinte. Durante um salto de segundo positivo no final de um dia, que ocorre em média a cada ano e meio, o número de horas Unix aumenta continuamente no dia seguinte durante o salto de segundo e depois no final do salto de segundo salta de volta por 1 (voltando ao início do dia seguinte). Por exemplo, isto é o que aconteceu em sistemas POSIX.1 estritamente conformes no final de 1998:
Números de tempo Unix são repetidos no segundo imediatamente a seguir a um segundo bissexto positivo. O número de tempo Unix 1483142400 é assim ambíguo: ele pode se referir tanto ao início do segundo salto (2016-12-31 23:59:60) ou ao final dele, um segundo depois (2017-01-01 00:00:00). No caso teórico quando ocorre um segundo bissexto negativo, nenhuma ambiguidade é causada, mas em vez disso há um intervalo de números de tempo Unix que não se referem a nenhum ponto no tempo UTC.
Um relógio Unix é muitas vezes implementado com um tipo diferente de tratamento do segundo bissexto positivo associado ao Protocolo de Tempo de Rede (NTP). Isto produz um sistema que não está em conformidade com o padrão POSIX. Veja a seção abaixo referente ao NTP para mais detalhes.
Ao lidar com períodos que não englobam um salto de segundo UTC, a diferença entre dois números de tempo Unix é igual à duração em segundos do período entre os pontos correspondentes no tempo. Esta é uma técnica computacional comum. No entanto, quando ocorrem segundos bissextos, tais cálculos dão a resposta errada. Em aplicações onde este nível de precisão é necessário, é necessário consultar uma tabela de segundos bissextos ao lidar com tempos Unix, e muitas vezes é preferível usar uma codificação de tempo diferente que não sofra deste problema.
Um número de tempo Unix é facilmente convertido de volta em um tempo UTC tomando o quociente e módulo do número de tempo Unix, modulo 86400. O quociente é o número de dias desde a época, e o módulo é o número de segundos desde a meia-noite UTC desse dia. Se for dado um número de hora Unix ambíguo devido a um salto de segundo positivo, este algoritmo interpreta-o como a hora logo após a meia-noite. Ele nunca gera uma hora que seja durante um segundo bissexto. Se for dado um número de hora Unix que seja inválido devido a um segundo bissexto negativo, ele gera uma hora UTC igualmente inválida. Se estas condições forem significativas, é necessário consultar uma tabela de segundos bissextos para detectá-las.
Variante não-síncrona baseada no Protocolo de Tempo de RedeEditar
Comumente um relógio Unix estilo Mills é implementado com um tratamento de segundos bissextos não sincronizado com a mudança do número de hora Unix. O número de hora inicialmente diminui onde deveria ter ocorrido um salto, e então ele salta para a hora correta 1 segundo após o salto. Isto facilita a implementação, e é descrito pelo papel da Mills. Isto é o que acontece em um salto positivo de segundo:
Isto pode ser decodificado corretamente prestando atenção na variável salto de segundo estado, que indica sem ambiguidade se o salto já foi realizado. A mudança da variável de estado é sincronizada com o salto.
Uma situação semelhante surge com um salto de segundo negativo, onde o segundo que é pulado é um pouco tarde demais. Muito brevemente o sistema mostra um número de tempo nominalmente impossível, mas isto pode ser detectado pelo estado TIME_DEL e corrigido.
Neste tipo de sistema o número de tempo Unix viola o POSIX em torno de ambos os tipos de salto de segundo. A recolha da variável de estado de segundo salto juntamente com o número de hora permite uma descodificação sem ambiguidades, pelo que o número de hora POSIX correcto pode ser gerado se desejado, ou a hora UTC completa pode ser armazenada num formato mais adequado.
A lógica de descodificação necessária para lidar com este estilo de relógio Unix também descodificaria correctamente um hipotético relógio em conformidade com o POSIX usando a mesma interface. Isto seria alcançado indicando o estado TIME_INS durante a totalidade de um segundo bissexto inserido, depois indicando TIME_WAIT durante a totalidade do segundo seguinte enquanto repete a contagem de segundos. Isto requer um tratamento síncrono do salto de segundos. Esta é provavelmente a melhor maneira de expressar o tempo UTC na forma de relógio Unix, através de uma interface Unix, quando o relógio subjacente é fundamentalmente não perturbado pelos segundos bissextos.
Variante baseada em TAIEdit
Uma outra variante, muito mais rara e não-conforme de manutenção de tempo Unix envolve a codificação de TAI em vez de UTC; alguns sistemas Linux são configurados desta forma. Como o TAI não tem segundos bissextos, e cada dia TAI tem exactamente 86400 segundos, esta codificação é na verdade uma contagem linear pura de segundos decorridos desde 1970-01-01T00:00:00 TAI. Isto torna a aritmética de intervalos de tempo muito mais fácil. Os valores de tempo destes sistemas não sofrem a ambiguidade que os sistemas POSIX ou NTP-driven têm.
Nestes sistemas é necessário consultar uma tabela de segundos bissextos para converter correctamente entre UTC e a representação pseudo-Unix-time. Isto se assemelha à maneira na qual as tabelas de fuso horário devem ser consultadas para converter de e para a hora civil; a base de dados de fuso horário da IANA inclui informações de segundos bissextos, e o código de amostra disponível a partir da mesma fonte utiliza essa informação para converter entre carimbos de horário baseados em TAI e a hora local. A conversão também corre em problemas de definição antes do início de 1972 da forma atual do UTC (ver seção base UTC abaixo).
Este sistema baseado em TAI, apesar de sua semelhança superficial, não é tempo Unix. Ele codifica os tempos com valores que diferem por vários segundos dos valores de tempo POSIX. Uma versão deste sistema foi proposta para inclusão na ISO C’s time.h
, mas apenas a parte UTC foi aceita em 2011. A tai_clock
existe, no entanto, em C++20.
Representando o númeroEdit
Um número de tempo Unix pode ser representado em qualquer forma capaz de representar números. Em algumas aplicações o número é simplesmente representado textualmente como uma string de dígitos decimais, levantando apenas problemas adicionais triviais. Entretanto, certas representações binárias de tempos Unix são particularmente significativas.
O Unix time_t
tipo de dado que representa um ponto no tempo é, em muitas plataformas, um inteiro assinado, tradicionalmente de 32 bits (mas veja abaixo), codificando diretamente o número de tempo Unix como descrito na seção anterior. Ser 32 bits significa que cobre um intervalo de cerca de 136 anos no total. A data mínima representativa é sexta-feira 1901-12-13, e a data máxima representativa é terça-feira 2038-01-19. Um segundo após 03:14:07 UTC 2038-01-19 esta representação irá transbordar. Este marco é antecipado com uma mistura de diversão e pavor – veja o problema do ano 2038.
Em alguns sistemas operacionais mais novos, time_t
foi ampliado para 64 bits. Isto expande os tempos representáveis por aproximadamente 293 bilhões de anos em ambas as direções, o que é mais de vinte vezes a idade atual do universo por direção.
Existiu originalmente alguma controvérsia sobre se o Unix time_t
deveria ser assinado ou não. Se não assinado, o seu alcance no futuro seria duplicado, adiando o transbordamento de 32 bits (por 68 anos). No entanto, seria então incapaz de representar tempos anteriores à época. O consenso é para que time_t
seja assinado, e esta é a prática usual. A plataforma de desenvolvimento de software para a versão 6 do sistema operacional QNX tem um 32-bit time_t
não assinado, embora versões mais antigas usassem um tipo assinado.
As especificações POSIX e Open Group Unix incluem a biblioteca padrão C, que inclui os tipos de tempo e funções definidas no arquivo de cabeçalho <time.h>
. O padrão ISO C afirma que time_t
deve ser um tipo aritmético, mas não exige nenhum tipo específico ou codificação para ele. POSIX requer time_t
para ser um tipo inteiro, mas não obriga a que seja assinado ou não.
Unix não tem tradição de representar directamente números de tempo Unix não-inteiros como fracções binárias. Em vez disso, tempos com sub-segundos de precisão são representados usando tipos de dados compostos que consistem de dois inteiros, sendo o primeiro um time_t
(a parte integral do tempo Unix), e o segundo sendo a parte fracional do número de tempo em milionésimos (em struct timeval
) ou bilionésimos (em struct timespec
). Estas estruturas fornecem um formato de dados com pontos fixos decimais, que é útil para algumas aplicações, e trivial para converter para outras.
base UTCEditar
A presente forma de UTC, com segundos bissextos, é definida apenas a partir de 1 de Janeiro de 1972. Antes disso, desde 1 de Janeiro de 1961 havia uma forma mais antiga de UTC em que não só havia passos de tempo ocasionais, que eram por números não-inteiros de segundos, mas também o segundo UTC era ligeiramente mais longo que o segundo SI, e mudava periodicamente para se aproximar continuamente da rotação da Terra. Antes de 1961 não havia UTC, e antes de 1958 não havia uma contagem de tempo atómica generalizada; nestas épocas, alguma aproximação do GMT (baseada directamente na rotação da Terra) era utilizada em vez de uma escala de tempo atómica.
A definição precisa do tempo Unix como codificação do UTC só é incontroversa quando aplicada à presente forma de UTC. A época Unix anterior ao início desta forma de UTC não afecta o seu uso nesta era: o número de dias de 1 de Janeiro de 1970 (a época Unix) a 1 de Janeiro de 1972 (o início do UTC) não está em questão, e o número de dias é tudo o que é significativo para o tempo Unix.
O significado dos valores de tempo Unix inferiores a +63072000 (ou seja, anteriores a 1 de Janeiro de 1972) não está definido com precisão. A base de tais tempos Unix é melhor entendida como uma aproximação não especificada do UTC. Os computadores daquela época raramente tinham relógios ajustados com precisão suficiente para fornecer carimbos temporais sub-segundos significativos em qualquer caso. O tempo Unix não é uma forma adequada de representar tempos anteriores a 1972 em aplicações que requerem precisão de subsegundos; tais aplicações devem, pelo menos, definir que forma de UT ou GMT utilizam.
As de 2009, está a ser considerada a possibilidade de terminar o uso de segundos bissextos em tempo civil. Um meio provável de executar esta mudança é definir uma nova escala de tempo, chamada Tempo Internacional, que inicialmente corresponda ao UTC mas que depois disso não tenha segundos bissextos, permanecendo assim a uma compensação constante do TAI. Se isto acontecer, é provável que o tempo Unix seja definido prospectivamente em termos desta nova escala de tempo, em vez de UTC. A incerteza sobre se isto irá ocorrer torna o tempo Unix prospectivo não menos previsível do que já é: se o UTC simplesmente não tivesse mais segundos bissextos, o resultado seria o mesmo.