År 2038 problem
År 2038-problemet (även känt som Y2038 , Y2K38 eller Epochalypse ) är en tidsformateringsbugg i datorsystem som representerar tider efter 03:14:07 UTC den 19 januari 2038.
Problemet finns i system som mäter Unix-tid – antalet sekunder som förflutit sedan Unix-epoken (00:00:00 UTC den 1 januari 1970) – och lagrar det i ett signerat 32-bitars heltal . Datatypen kan endast representera heltal mellan −(2 31 ) och 2 31 − 1 , vilket betyder att den senaste tiden som kan kodas korrekt är 2 31 − 1 sekunder efter epok (03:14:07 UTC den 19 januari 2038) . Ett försök att öka till följande sekund (03:14:08) kommer att få heltal att svämma över , vilket sätter dess värde till −(2 31 ), vilket system kommer att tolka som 2 31 sekunder före epok (20:45:52 UTC den 13 december 1901). Problemet liknar till sin natur år 2000 - problemet .
Datorsystem som använder tid för kritiska beräkningar kan stöta på allvarliga fel om Y2038-problemet inte åtgärdas. Vissa applikationer som använder framtida datum har redan stött på buggen. De mest sårbara systemen är de som sällan eller aldrig uppdateras, såsom äldre och inbyggda system . Det finns ingen universell lösning på problemet, även om många moderna system har uppgraderats för att mäta Unix-tid med tecken på 64-bitars heltal som inte kommer att svämma över på 292 miljarder år, vilket är ungefär 21 gånger universums beräknade ålder .
Orsak
Många datorsystem mäter tid och datum som Unix-tid , en internationell standard för digital tidtagning. Unix-tid definieras som antalet sekunder som förflutit sedan 00:00:00 UTC den 1 januari 1970 (en godtyckligt vald tid), som har kallats Unix-epoken .
Unix-tid har historiskt sett kodats som ett signerat 32-bitars heltal , en datatyp som består av 32 binära siffror (bitar) som representerar ett heltalsvärde, med "signerad" som betyder att talet lagras i Twos komplementformat . Således kan ett 32-bitars heltal endast representera heltalsvärden från −(2 31 ) till 2 31 − 1 inklusive. Följaktligen, om ett signerat 32-bitars heltal används för att lagra Unix-tid, är den senaste tiden som kan lagras 2 31 − 1 (2 147 483 647) sekunder efter epok, vilket är 03:14:07 tisdagen den 19 januari 2038. Systems ett försök att öka detta värde med ytterligare en sekund till 2 31 sekunder efter epok (03:14:08) kommer att drabbas av heltalsspill , oavsiktligt vända teckenbiten för att indikera ett negativt tal. Detta ändrar heltalsvärdet till −(2 31 ), eller 2 31 sekunder före epok snarare än efter , vilket system kommer att tolka som 20:45:52 fredagen den 13 december 1901. Härifrån kommer systemen att fortsätta att räkna uppåt, mot noll, och sedan upp genom de positiva heltal igen. Eftersom många datorsystem använder tidsberäkningar för att köra kritiska funktioner, kan buggen leda till allvarliga fel.
Sårbara system
Alla system som använder datastrukturer med 32-bitars tidsrepresentationer har en inneboende risk att misslyckas. En fullständig lista över dessa datastrukturer är praktiskt taget omöjlig att härleda, men det finns välkända datastrukturer som har Unix-tidsproblemet:
- Filsystem (många filsystem använder endast 32 bitar för att representera tider i inoder )
- Binära filformat (som använder 32-bitars tidsfält)
- Databaser (som har 32-bitars tidsfält)
- Databasfrågespråk (som SQL ) som har
UNIX_TIMESTAMP()-
liknande kommandon
Inbyggda system
Inbäddade system som använder datum för antingen beräkning eller diagnostisk loggning kommer med största sannolikhet att påverkas av Y2038-problemet. Trots den moderna generationsuppdateringen på 18–24 månader inom datorsystemteknik, är inbyggda system utformade för att hålla hela livslängden för maskinen där de är en komponent. Det är tänkbart att vissa av dessa system fortfarande kan vara i bruk under 2038. Det kan vara opraktiskt eller i vissa fall omöjligt att uppgradera programvaran som kör dessa system, vilket i slutändan kräver utbyte om 32-bitars begränsningarna ska korrigeras.
Många transportsystem från flyg till bilar använder i stor utsträckning inbyggda system. I bilsystem kan detta inkludera låsningsfria bromssystem (ABS), elektronisk stabilitetskontroll (ESC/ESP), traction control (TCS) och automatisk fyrhjulsdrift ; flygplan får använda tröghetsstyrningssystem och GPS-mottagare . En annan stor användning av inbyggda system är i kommunikationsenheter, inklusive mobiltelefoner och Internet-aktiverade apparater (t.ex. routrar , trådlösa åtkomstpunkter , IP-kameror ) som förlitar sig på att lagra en korrekt tid och datum och i allt högre grad bygger på Unix-liknande operativsystem. Till exempel gör Y2038-problemet att vissa enheter som kör 32-bitars Android kraschar och inte startar om när tiden ändras till det datumet.
Detta innebär dock inte att alla inbyggda system kommer att drabbas av Y2038-problemet, eftersom många sådana system inte kräver åtkomst till datum. För de som gör det kommer de system som bara spårar skillnaden mellan tider/datum och inte absoluta tider/datum, av beräkningens natur, inte att uppleva några större problem. Detta är fallet för fordonsdiagnostik baserad på lagstadgade standarder som CARB ( California Air Resources Board) .
Tidiga problem
I maj 2006 dök det upp rapporter om en tidig manifestation av Y2038-problemet i AOLserver- programvaran. Mjukvaran designades med en kludge för att hantera en databasförfrågan som "aldrig" skulle ta slut. Istället för att specifikt hantera detta specialfall, specificerade den initiala designen helt enkelt ett godtyckligt time-outdatum i framtiden. Standardkonfigurationen för servern angav att begäran skulle timeout efter en miljard sekunder. En miljard sekunder (drygt 31 år, 251 dagar, 1 timme, 46 minuter och 40 sekunder) efter 01:27:28 UTC den 13 maj 2006 är efter stoppdatumet 2038. Efter denna tid flödade time-outberäkningen över och returnerade ett datum som faktiskt låg i det förflutna, vilket fick programvaran att krascha. När problemet upptäcktes var AOLServer-operatörerna tvungna att redigera konfigurationsfilen och ställa in timeout till ett lägre värde.
Lösningar
Det finns ingen universell lösning för år 2038-problemet. Till exempel, i C-språket , skulle varje ändring av definitionen av time_t
-datatypen resultera i kodkompatibilitetsproblem i alla applikationer där datum- och tidsrepresentationer är beroende av naturen hos det signerade 32-bitars time_t
-heltalet. Om till exempel ändra time_t
till ett osignerat 32-bitars heltal, vilket skulle utöka intervallet till 2106 (specifikt 06:28:15 UTC söndagen den 7 februari 2106), skulle det negativt påverka program som lagrar, hämtar eller manipulerar tidigare datum till 1970, eftersom sådana datum representeras av negativa tal. Att öka storleken på time_t
-typen till 64 bitar i ett befintligt system skulle orsaka inkompatibla ändringar i layouten av strukturer och det binära gränssnittet för funktioner.
De flesta operativsystem som är utformade för att köras på 64-bitars hårdvara använder redan signerade 64-bitars time_t
heltal. Att använda ett signerat 64-bitarsvärde introducerar ett nytt omslutningsdatum som är över tjugo gånger högre än universums beräknade ålder : cirka 292 miljarder år från nu. Möjligheten att göra beräkningar på datum begränsas av det faktum att tm_year
använder ett signerat 32-bitars heltalsvärde som börjar vid 1900 för året. Detta begränsar året till maximalt 2 147 485 547 (2 147 483 647 + 1900).
Alternativa förslag har gjorts (av vilka några redan används), som att lagra antingen millisekunder eller mikrosekunder sedan en epok (vanligtvis antingen 1 januari 1970 eller 1 januari 2000) i ett signerat 64-bitars heltal, vilket ger ett minsta intervall på 300 000 år i mikrosekundsupplösning. I synnerhet kommer Javas användning av 64-bitars långa heltal överallt för att representera tid som "millisekunder sedan 1 januari 1970" att fungera korrekt under de kommande 292 miljoner åren. Andra förslag på nya tidsrepresentationer ger olika precisioner, intervall och storlekar (nästan alltid bredare än 32 bitar), samt löser andra relaterade problem, såsom hanteringen av skottsekunder . I synnerhet är TAI64 en implementering av International Atomic Time (TAI), den nuvarande internationella realtidsstandarden för att definiera en andra och referensram.
Implementerade lösningar
- Från och med Ruby version 1.9.2, är buggen med år 2038 fixad, genom att omimplementera tid för att inte ha något minimum eller maximum.
- Från och med NetBSD version 6.0 (släppt i oktober 2012), använder NetBSD-operativsystemet en 64-bitars
time_t
för både 32-bitars och 64-bitars arkitekturer. Applikationer som kompilerades för en äldre NetBSD-version med 32-bitarstime_t
stöds via ett binärt kompatibilitetslager, men sådana äldre applikationer kommer fortfarande att lida av Y2038-problemet. -
OpenBSD sedan version 5.5, släppt i maj 2014, använder också en 64-bitars
time_t
för både 32-bitars och 64-bitars arkitekturer. I motsats till NetBSD finns det inget binärt kompatibilitetslager. Därför kan applikationer som förväntar sig en 32-bitarstime_t
och applikationer som använder något annat fråntime_t
för att lagra tidsvärden gå sönder. -
Linux använde ursprungligen en 64-bitars
time_t
endast för 64-bitars arkitekturer; den rena 32-bitars ABI ändrades inte på grund av bakåtkompatibilitet. Från och med version 5.6 av 2020 stöds 64-bitarstime_t också på 32-bitars arkitekturer. Detta gjordes främst för
inbyggda Linux- systems skull . -
FreeBSD använder 64-bitars
time_t
för alla 32-bitars och 64-bitars arkitekturer utom 32-bitars i386, som använder signerad 32-bitarstime_t
istället. - x32 ABI för Linux (som definierar en miljö för program med 32-bitars adresser men som kör processorn i 64-bitars läge) använder en 64-bitars
time_t
. Eftersom det var en ny miljö behövdes det inga speciella kompatibilitetsåtgärder. -
Network File System version 4 har definierat sina tidsfält som
struct nfstime4 {int64_t seconds; uint32_t nseconds;}
sedan december 2000. Värden större än noll för sekundfältet anger datum efter 0-timmen, 1 januari 1970. Värden mindre än noll för sekundersfältet anger datum före 0-timme, 1 januari 1970. I båda fallen ska fältet nsekunder (nanosekunder) läggas till i sekundfältet för den sista tidsrepresentationen. - Ext4 - filsystemet, när det används med inodstorlekar större än 128 byte, har ett extra 32-bitars fält per tidsstämpel, varav 30 bitar används för nanosekundersdelen av tidsstämpeln, och de andra 2 bitarna används för att utöka tidsstämpelområdet till år 2446.
- XFS - filsystemet, som börjar med Linux 5.10, har en valfri "stora tidsstämplar"-funktion som utökar tidsstämpelintervallet till år 2486.
- Medan de inbyggda API:erna för OpenVMS kan stödja tidsstämplar upp till 31 juli 31086, använder C runtime library (CRTL) 32-bitars heltal för
time_t
. Som en del av Y2K-efterlevnadsarbete som utfördes 1998, modifierades CRTL för att använda osignerade 32-bitars heltal för att representera tid; förlänger intervallettime_t
till den 7 februari 2106. - Från och med MySQL 8.0.28 hanterar funktionerna
FROM_UNIXTIME()
,UNIX_TIMESTAMP()
ochCONVERT_TZ()
64-bitarsvärden på plattformar som stöder dem. Detta inkluderar 64-bitarsversioner av Linux, MacOS och Windows. I relationsdatabasversioner före augusti 2021 kommer inbyggda funktioner somUNIX_TIMESTAMP()
att returnera 0 efter 03:14:07 UTC den 19 januari 2038.
Se även
- År 2000 problem , ett liknande problem som inträffade med en rollover i år
- Tidsformaterings- och lagringsbuggar listar andra liknande problem, ofta orsakade av rollover liknande orsaken till detta år 2038-problem.
- En övergång av GPS-veckonummer kommer av en slump att ske senare under 2038, av en annan anledning än detta år 2038-problem.
Anteckningar
externa länkar
- Y2038 Proofness Design glibc Wiki
- Inlägg i How Stuff Works
- The Project 2038 Vanliga frågor
- Kritiska och viktiga datum 2038
- En 2038-säker ersättning för time.h på 32-bitars system
- Baraniuk, Chris (5 maj 2015). "Nummerfelet som kan leda till katastrof" . BBC Future .
- Clewett, James. "2 147 483 647 – Tidens slut [Unix]" . Numberphile . Brady Haran . Arkiverad från originalet den 22 maj 2017 . Hämtad 7 april 2013 .