År 2038-problemet och digital tid

Från Unix.se, den fria unixresursen.

Innehåll

Introduktion

Alla har naturligtvis hört talas om år 2000-problemet (med tanke på hur mycket det uppmärksammades även i konventionell media) och många är säkert också medvetna om att Unixsystem inte hade några omfattande sådana. Vad detta beror på är det däremot möjligt att färre är helt på det klara med. Detta ämnar den här artikeln klargöra, samtidigt som en kort introduktion ges för hur C (och därmed Unix) hanterar datum och tid.

Unix

De allra flesta c-program som hanterar datum och tider använder sig av det standardiserade tidshanteringsbiblioteket "time.h" (som är en del av alla standarduppfyllande c-implementationer). I detta definieras en abstrakt datatyp vid namn time_t som räknar tiden i antal sekunder sedan midnatt nyårsdagen 1970 GMT (Unix skapades i AT&T:s Bell Labs 1969). Eftersom datorn i sig inte har något som helst koncept över varken tider eller andra abstrakta datatyper måste detta renderas på något för datorn förståeligt sätt. De allra flesta implementationer av C har här använt en 32-bitars signed int, vilket självfallet sätter vissa begränsningar på hur långt in i framtiden man kan komma. Det visar sig att de 2^31 (32-bitar varav en går åt för att beteckna tecknet på talet) = 2147483648 sekunder detta innebär representerar 2^31/(365*24*60*60) = ungefär 68 år. Då tiden räknas från år 1970 innebär detta att ett typiskt Unixsystem inte kan handskas med tider eller datum längre fram i tiden än så. Detta innebär att alla möjliga hemska saker kommer hända om mindre än 36 år (ni kan säkert föreställa er exempel själva om ni lyssnat det minsta på domedagsprofeterna i slutet av 90-talet) om vi inte gör något åt detta. (För att vara mer exakt är det den 19 januari 2038, klockan 7 minuter över 4 GMT som den stora händelsen inträffar.) Hur ligger Unix till jämfört med andra system?

Andra system

Stordatorer

Det här är precis den gruppen som låg som värst till för några år sedan. Tänk er stora klumpiga IBM-datorer som kör COBOL-program skrivna för ett halvt sekel sedan som bollar siffror fram och tillbaka i bankernas affärssystem så vet ni vad som menas. Dessa är förmodligen (förutom ett antal fulhack som säkert gjordes för att temporärt förlänga fristen deras sätt att ange datum med två siffror gav dem) omskrivna till att använda tal stora nog att hantera åtminstone 4 siffror och kan förväntas tuffa på länge till.

En stor skillnad på Unixsystem och den blandade kompotten antika stordatorsystem är dock den omfattande standardiseringen som skett i Unix (såsom SUS och POSIX) och programmeringsspråket C (ISO-standardiserat). Eftersom så gott som alla använder samma rutiner är det bara på ett ställe en eventuell ändring behöver göras. Det faktum att Unixkulturen i hög utsträckning distributerar mjukvara i form av källkod lindrar också i någon grad det faktum att all gammal kod måste omkompileras.

Mac OS

Citat från developer.apple.com [1] (http://developer.apple.com/technotes/tn/tn1049.html):

The original date and time utilities, introduced with the original Macintosh 128K in 1984, used a 32-bit value to store seconds, starting at 12: 00: 00 a.m., January 1, 1904. Since Apple used a 32-bit value to store seconds, this means that the last date represented in this 32-bit value is 6: 28: 15 a.m. on February 6, 2040. The current date and time utilities, documented in Inside Macintosh: Operating System Utilities, use a 64-bit signed value. This covers dates from 30081 B.C. to 29940 A.D.

Macintoshsystem bör således också vara utom fara den närmaste framtiden.

IBM PC

Alla IBM-kompatibla PC-datorer hanterar tid internt på ett sätt som liknar det Unix (och alla vanliga implementationer av det standardiserade C-biblioteket) använder, med skillnaden att en unsigned int används samt att utgångsåret är 1980. Detta gör att dessa förmodligen kommer orsaka problem runt år 2116 men detta är med största sannolikhet inte något problem överhuvudtaget, då det är väldigt sällan hårdvara förblir i bruk så länge. Värt att notera som kuriosa om inte annat dock.

Amiga

För kuriosans skull tar vi även upp Amiga.

Amigan har alltid representerat tid på samma sätt som Unix, men 8 år efter (ie. med början 1978). I Amigans fall är tidshanteringen dock inte alls lika standardiserad. AmigaDOS (delen av AmigaOS som hanterar kommandoprompten och filhantering, bland annat) sparar tiden som en signed int, vilket innebär att det kritiska datumet för Amigans del blir precis 8 år efter det för Unix, det vill säga 2046.

I den större delen av alla applikationer (däribland merparten av AmigaOS) används dock unsigned int, vilket utökar livslängden till år 2114. Detta borde inte vara något jätteproblem å andra sidan. Antalet Amigor som används i kritiska system kan nog räknas på ena handens fingrar. Med ett par av dem avhuggna. Förhoppningsvis finns det fortfarande kvar entusiaster som använder dessa otroligt välgjorda burkar om 40 år dock, så det skadar säkerligen inte att ta upp det.

Windows 95/98

Dessa synnerligen föråldrade men fortfarande flitigt använda operativsystem lärde sig tydligen inte någonting från de tekniska debatterna inför år 2000. Istället för att mer eller mindre permanent lösa problemet (som stordatorerna förhoppningsvis gjort) valde man att skjuta upp det ett par år. Datum sparas som tvåsiffriga tal med ursprung 1930. Detta innebär att 1 januari 2030 blir ett kritiskt datum för dessa system, men förhoppningsvis är det ingen som fortfarande använder dem då..

Windows NT

Windows NT representerar tid på ett mycket mer raffinerat sätt, nämligen som en 64-bitars int innehållande antalet 100-tal nanosekunder sedan första januari 1601. Detta skjuter fristen så långt fram som till år 2184, men det är återigen ingenting att oroa sig för; så länge kommer inte NT leva.

Lösningar

Två möjliga vettiga lösningar på problemet, som båda självfallet kräver att alla existerande binärer kompileras om, är:

  1. Gå över till att representera time_t som en 64-bitars signed int. Detta verkar vara den absolut bästa lösningen i och med att 64-bitars system blir allt vanligare. 2^63 sekunder är en ofantligt stor tidsrymd; med de nu rådande uppfattningarna inom forskarvärlden ungefär 20 gånger universums ålder. Den kritiska frågan är om 64-bitars system kommer vara _tillräckligt_ vanliga i början av 2030-talet.
  2. Fortsätta med 32-bitars ints, men göra dem unsigned. Detta verkar vid första anblicken vara en smart lösning som varken kräver utveckling av nya sofistikerade datatyper eller ännu för de flesta allt för dyr hårdvara. Det har dock den olycksamma nackdelen att det helt skulle bryta bakåtkompabiliteten med de enorma mängder fungerande program och rutiner skrivna i C som räknar med att kunna uttrycka skillnader mellan två tider som en enkel differens mellan två variabler av typ time_t. En lika lustig som insiktsfull anekdot på det här ämnet är http://mail-index.netbsd.org/tech-userlevel/1998/06/04/0000.html.

Man noterar att inget av dessa lösningsförslag kräver någon som helst ändring i källkoden i någon av de berörda programmen (förutsatt att de är skrivna portabelt och inte räknar med att kunna uttrycka negativa tider, något som dock ingalunda kan förutsättas i alla fall). Detta är som ovan antydits en konsekvens av den strikta åtföljan till standarder som finns inom Unixkulturen. Vi "vanligt folk" kan således känna oss relativt trygga i förvissningen om att någon gång (förmodligen långt före de första konsekvenserna av detta märks av) alla använda implementationer av libc kommer hantera detta på ett graciöst sätt. Unix kommer överleva. :)

Personliga verktyg