Por que o Unix armazena registros de data e hora em um número inteiro assinado?

24

Por que um número inteiro assinado é usado para representar registros de data e hora? Há um começo claramente definido em 1970, que é representado como 0, então por que precisaríamos de números antes disso? Os carimbos de data e hora negativos são usados ​​em algum lugar?

Bakudan
fonte
2
É por isso que Nostradamus não pôde usar seu computador para escrever suas previsões para os anos 3000 + ... isso causaria um estouro e mostraria suas datas como negativas. Eu acho que eles chamaram isso de bug do Y3K ou algo assim!
Jeach 01/12/19
3
Os romanos antigos tiveram um problema ainda pior quando os números do ano mudaram de negativo para positivo. Eles teriam chamado o problema de Y0K se tivessem uma maneira de expressar o número zero. 8-)}
Keith Thompson

Respostas:

35

As versões anteriores do C não tinham números inteiros não assinados. (Alguns programadores usavam ponteiros quando precisavam de aritmética sem sinal.) Não sei o que veio primeiro, otime() função ou os tipos não assinados, mas suspeito que a representação foi estabelecida antes que os tipos não assinados estivessem disponíveis universalmente. E 2038 foi longe o suficiente no futuro para que provavelmente não valia a pena se preocupar. Duvido que muitas pessoas pensassem que o Unix ainda existiria até então.

Outra vantagem de um sinal time_té que estendê-lo para 64 bits (o que já está acontecendo em alguns sistemas) permite representar vezes centenas de bilhões de anos no futuro, sem perder a capacidade de representar tempos antes de 1970. (É por isso que me oponho a mudar para um Não assinado de 32 bits time_t; temos tempo suficiente para fazer a transição para 64 bits.)

Keith Thompson
fonte
7
A timefunção é anterior à época: o Unix v1 (em 1971) contava em unidades de 1/60 de segundo, a partir da meia-noite de 01/01/1971. Já era um bug conhecido que “o usuário com espírito cronológico notará que 2 ** 32 sessenta de segundo são apenas cerca de 2,5 anos.” unsigned Foi introduzido pela K&R em 1978 , muito depois da época de 1970 ter sido estabelecida.
Gilles 'SO- stop be evil'
Eu fiz um teste rápido e na minha caixa Linux de 64 bits. gmtimee localtimemax out no ano 2147483647 (com o segundo seguinte depois de atribuir -2147483648 como o ano). Portanto, para ultrapassar os 55 bits de tempo, alguém precisará atualizar a rotina de saída para usar um int de 64 bits para o ano, em vez de um int de 32 bits não assinado. Espero que alguém cuide desse bug nos próximos bilhões de anos.
freiheit
@ Freiheit: Interessante. O problema é que o struct tmtipo tem um membro tm_year(representando anos desde 1900) que é do tipo int. Os sistemas de 64 bits podem facilmente ter um de 64 bits time_t, mas geralmente têm 32 bits int. (Se charfor 8 bits e int64 bits, shortpode ser 16 ou 32 bits e não haverá tipo predefinido para o outro tamanho.) Mas time()provavelmente é a única função <time.h>que realmente requer suporte no nível do sistema; você pode escrever seu próprio código para converter time_tvalores em seqüências legíveis por humanos.
Keith Thompson
12

É para apoiar registros de data e hora antes de 1º de janeiro de 1970.

anfetamaquina
fonte
1
Isso faz apenas 68 anos no passado - 1902. Isso parece um pouco.
Bakudan
2
O POSIX não precisa time_tter apenas 32 bits; já é de 64 bits em muitos sistemas.
Keith Thompson
1
mktime()A função retorna -1em caso de erro, portanto, é provavelmente impossível distinguir entre carimbos de data e hora corretos antes de 01-01-2009 e erro ts. Datas apparenlty antes 1970-01-01 são proibidos
DIMG
@ DimG: É difícil distinguir entre um erro e o carimbo de data / hora específico 1969-12-31 23:59:59 UTC. Um valor negativo diferente de não -1ambíguo.
Keith Thompson
1
@mtraceur: O padrão C não exige uma falha na mktime()chamada para definir errno. (POSIX faz.)
Keith Thompson