Pourquoi Unix stocke-t-il les horodatages dans un entier signé?

24

Pourquoi un entier signé est-il utilisé pour représenter des horodatages? Il y a un début clairement défini à 1970 qui est représenté par 0, alors pourquoi aurions-nous besoin de chiffres avant cela? Des horodatages négatifs sont-ils utilisés quelque part?

Bakudan
la source
2
C'est pourquoi Nostradamus ne pouvait pas utiliser son ordinateur pour écrire ses prédictions pour les années 3000+ ... cela provoquerait un débordement et afficherait ses dates comme négatives. Je pense qu'ils l'ont appelé le bug Y3K ou quelque chose comme ça!
Jeach
3
Les anciens Romains ont eu un problème encore pire lorsque les chiffres de l'année sont passés de négatifs à positifs. Ils l'auraient appelé le problème Y0K s'ils avaient eu un moyen d'exprimer le nombre zéro. 8-)}
Keith Thompson

Réponses:

35

Les premières versions de C n'avaient pas d'entiers non signés. (Certains programmeurs utilisaient des pointeurs lorsqu'ils avaient besoin d'une arithmétique non signée.) Je ne sais pas lequel est venu en premier, la time()fonction ou les types non signés, mais je soupçonne que la représentation a été établie avant que les types non signés ne soient universellement disponibles. Et 2038 était suffisamment loin dans le futur pour que cela ne valait probablement pas la peine de s'inquiéter. Je doute que beaucoup de gens pensaient qu'Unix existerait encore d'ici là.

Un autre avantage d'un signé time_test que son extension à 64 bits (ce qui se produit déjà sur certains systèmes) vous permet de représenter plusieurs centaines de milliards d'années dans le futur sans perdre la capacité de représenter des temps avant 1970. (C'est pourquoi je m'oppose au passage à un 32 bits non signé time_t ; nous avons suffisamment de temps pour passer à 64 bits.)

Keith Thompson
la source
7
La timefonction est plus ancienne que l'époque: Unix v1 (en 1971) compté en unités de 1 / 60e de seconde, à partir de minuit le 1971/01/01. C'était déjà un bug connu que «L'utilisateur soucieux de la chronologie notera que 2 ** 32 soixantièmes de seconde n'est que d'environ 2,5 ans.» A unsigned été introduit par K&R en 1978 , bien après l'époque de 1970.
Gilles 'SO- arrête d'être méchant'
J'ai fait un test rapide et sur ma boîte Linux 64 bits. gmtimeet localtimemax out en l'an 2147483647 (avec la seconde suivante après avoir donné -2147483648 comme année). Donc, pour obtenir bien plus de 55 bits de temps, quelqu'un devra mettre à jour la routine de sortie pour utiliser un entier 64 bits pour l'année au lieu d'un entier 32 bits non signé. J'espère que quelqu'un s'occupera de ce bogue au cours des deux prochains milliards d'années.
freiheit
@freiheit: Intéressant. Le problème est que le struct tmtype a un membre tm_year(représentant des années depuis 1900) qui est de type int. Les systèmes 64 bits peuvent facilement avoir un 64 bits time_t, mais ils ont généralement un 32 bits int. (Si charest 8 bits et int64 bits, alors il shortpeut être de 16 ou 32 bits, et il n'y aura pas de type prédéfini pour l'autre taille.) Mais time()c'est probablement la seule fonction <time.h>qui nécessite vraiment une prise en charge au niveau du système; vous pouvez écrire votre propre code pour convertir des time_tvaleurs en chaînes lisibles par l'homme.
Keith Thompson
12

C'est pour prendre en charge les horodatages et les dates avant le 1er janvier 1970.

amphétamachine
la source
1
Cela fait seulement 68 ans dans le passé - 1902. Cela semble un peu.
Bakudan
2
POSIX ne nécessite time_tpas seulement 32 bits; c'est déjà 64 bits sur de nombreux systèmes.
Keith Thompson,
1
mktime()La fonction retourne -1en cas d'erreur, il est donc probablement impossible de distinguer les horodatages corrects avant le 01/01/1970 et les ts d'erreur. Les dates apparentes avant le 01-01-1970 sont interdites
DimG
@DimG: Il est difficile de faire la distinction entre une erreur et l'horodatage spécifique 1969-12-31 23:59:59 UTC. Une valeur négative autre que non -1ambiguë.
Keith Thompson
1
@mtraceur: La norme C ne nécessite pas d' mktime()appel défaillant à définir errno. (POSIX le fait.)
Keith Thompson