A Unix-idő vagy POSIX-idő a számítástechnikában a UTC szerinti 1970. január 1. 00:00:00 óta eltelt másodpercek száma, a szökőmásodperceket nem számolva. A Unix-szerű operációs rendszerek mellett számos más alkalmazásban is használják. A Unix-idő, bár sokan tévesen annak hiszik, valójában nem lineáris reprezentációja az időnek, és nem valódi reprezentációja a UTC-nak, mert a szökőmásodperceket nem lehet vele megadni.

Definíció A Unix-idő két egymásra épülő kódolásból áll, amik külön is használhatók. Az első egy időpontot egy valós számmá konvertál, a második pedig a számot egy bitsorozattá.

Az idő átalakítása számmá

A modern Unix-idő a UTC-on alapszik. A UTC másodperceket számol, és az időt napokra osztja. Egy UTC nap általában másodperc, de vagy másodperc is, ha egy szökőmásodpercet iktatnak be vagy vesznek el, hogy a Föld forgásával szinkronban tartsák. A Unix-idő nulla pontja az ún. „Unix epoch”, azaz a UTC szerinti 1970. január 1. 00:00:00. (A probléma ezzel a definícióval az, hogy a UTC jelen formájában csak 1972 óta létezik. Erre a kérdésre később visszatérünk.) A szakasz hátralévő része a rövidség kedvéért az ISO 8601 dátumformátumot használja, amiben az Unix epoch 1970-01-01T00:00:00Z.

A Unix-idő mindennap másodperccel nő, így például 2004-09-16T00:00:00Z, ami nappal a Unix epoch után van, Unix-időben × = . A Unix epoch előtti időpontok hasonlóan ábrázolhatóak negatív számok segítségével: 1957-10-04T00:00:00Z, 4472 nappal a Unix epoch előtt, a Unix idő szerint -4472 × = .

A dátumból így kapott számhoz hozzá kell adni az éjfél óta eltelt másodpercek számát, hogy megkapjuk a teljes Unix-időt. Így például 2004-09-16T17:55:43.54Z, ami másodperccel van éjfél után, Unix-időben + = . Az összeg második tagja természetesen a Unix epoch előtti dátumoknál is pozitív.

A fentiekből következik, hogy egy normális ( másodperces) UTC napon a Unix-idő éjfélkor is folytonosan nő. Például a fenti példában szereplő nap végén az idő különféle reprezentációi így változnak (a TAI a UTC-hoz hasonló, de szökőmásodpercek nélküli időreprezentáció):

+ A Unix-idő alakulása éjfélkor egy normális UTC naponTAIUTCUnix-idő2004-09-17T00:00:30.752004-09-16T23:59:58.752004-09-17T00:00:31.002004-09-16T23:59:59.002004-09-17T00:00:31.252004-09-16T23:59:59.252004-09-17T00:00:31.502004-09-16T23:59:59.502004-09-17T00:00:31.752004-09-16T23:59:59.752004-09-17T00:00:32.002004-09-17T00:00:00.002004-09-17T00:00:32.252004-09-17T00:00:00.252004-09-17T00:00:32.502004-09-17T00:00:00.502004-09-17T00:00:32.752004-09-17T00:00:00.752004-09-17T00:00:33.002004-09-17T00:00:01.002004-09-17T00:00:33.252004-09-17T00:00:01.25

Ha a UTC nap egy szökőmásodperc miatt nem pontosan másodperc hosszú, a Unix-időben egy szakadás lép fel. A Unix idő pontosan -zal nő mindennap, függetlenül a nap hosszától. Ha egy szökőmásodperc elmarad (ilyenre eddig nem volt még példa), a Unix-idő egy egységet ugrik azon a helyen, ahonnan a szökőmásodpercet törölték (ami a nap vége). Ha beszúrnak egy szökőmásodpercet (ez átlagosan másfél évente történik meg), a Unix-idő folytonosan nő a szökőmásodperc ideje alatt, majd a szökőmásodperc végén egy egységet visszaugrik. Például a POSIX szabványt pontosan betartó rendszerekben 1998 végén ez így nézett ki:

+ A Unix-idő alakulása éjfélkor, ha beszúrnak egy szökőmásodpercetTAIUTCUnix-idő1999-01-01T00:00:29.751998-12-31T23:59:58.75915 148 798.751999-01-01T00:00:30.001998-12-31T23:59:59.00915 148 799.001999-01-01T00:00:30.251998-12-31T23:59:59.25915 148 799.251999-01-01T00:00:30.501998-12-31T23:59:59.50915 148 799.501999-01-01T00:00:30.751998-12-31T23:59:59.75915 148 799.751999-01-01T00:00:31.001998-12-31T23:59:60.00915 148 800.001999-01-01T00:00:31.251998-12-31T23:59:60.25915 148 800.251999-01-01T00:00:31.501998-12-31T23:59:60.50915 148 800.501999-01-01T00:00:31.751998-12-31T23:59:60.75915 148 800.751999-01-01T00:00:32.001999-01-01T00:00:00.00915 148 800.001999-01-01T00:00:32.251999-01-01T00:00:00.25915 148 800.251999-01-01T00:00:32.501999-01-01T00:00:00.50915 148 800.501999-01-01T00:00:32.751999-01-01T00:00:00.75915 148 800.751999-01-01T00:00:33.001999-01-01T00:00:01.00915 148 801.001999-01-01T00:00:33.251999-01-01T00:00:01.25915 148 801.25

Mint látható, a nem egyértelmű: vonatkozhat a szökőmásodperc és az azt követő másodperc közepére is. Negatív szökőmásodperc esetén nem lenne kétértelműség, viszont lenne olyan értéke a Unix-időnek, ami nem felel meg semmilyen valós időpontnak.

A Unix rendszerek óráinak szökőmásodperc-kezelése gyakran eltér ettől, és a Network Time Protocolt követi. Az ilyen, nem POSIX-konform rendszereket a következő szakasz írja le.

Ha két időpont között nincs szökőmásodperc, a megfelelő Unix-idők különbsége egyenlő a két időpont közötti időtartammal, másodpercben. Ezt gyakran kihasználják a számítástechnikában; az ilyen számítások azonban a szökőmásodpercek miatt pontatlanná válhatnak. Abban az esetben, amikor a két időpont között pozitív szökőmásodperc-eltérés van, az algoritmusok ezt éjfél utáni időnek fogják értelmezni, és nem fogják az időt a szökőmásodperc alatt kiszámolni. Amennyiben az Unix-idő a negatív szökőmásodperc következtében értelmezhetetlen, az algoritmus egy nem-valós UTC időt számol ki. Azokban az alkalmazásokban, ahol másodperces vagy nagyobb pontosságra van szükség, szökőmásodperc-táblázatokat használnak vagy más időreprezentációt választanak.

A Unix-időből egyszerűen visszaállítható a UTC-idő: a Unix-időt -zal osztva a hányados az epoch óta eltelt napok számát adja meg, míg a maradék az aznap éjfél óta eltelt másodpercek számát mutatja.

Aszinkron NTP-alapú változat Általában a Mills-stílusú Unix óra, amely implementált szökőmásodperc-kezeléssel rendelkezik, nem szinkron a Unix-idővel. A Unix-idő akkor nő, amikor szökőmásodpercnek kellene jönnie, majd néhány milliszekundummal később szökik. Azért van ez így, hogy megkönnyítsék az implementációt és mellékesen Mills tanulmánya alapján is ez ajánlott. A következő történik pozitív szökőmásodperc esetén:

+ Aszinkron Mills-stílusú Unix-idő éjfélkor, mikor egy UTC szökőmásodperc következik beTAIUTCállapotUnix-idő1999-01-01T00:00:29.751998-12-31T23:59:58.75TIME_INS915 148 798.751999-01-01T00:00:30.001998-12-31T23:59:59.00TIME_INS915 148 799.001999-01-01T00:00:30.251998-12-31T23:59:59.25TIME_INS915 148 799.251999-01-01T00:00:30.501998-12-31T23:59:59.50TIME_INS915 148 799.501999-01-01T00:00:30.751998-12-31T23:59:59.75TIME_INS915 148 799.751999-01-01T00:00:31.001998-12-31T23:59:60.00TIME_INS915 148 800.001999-01-01T00:00:31.251998-12-31T23:59:60.25TIME_OOP915 148 799.251999-01-01T00:00:31.501998-12-31T23:59:60.50TIME_OOP915 148 799.501999-01-01T00:00:31.751998-12-31T23:59:60.75TIME_OOP915 148 799.751999-01-01T00:00:32.001999-01-01T00:00:00.00TIME_OOP915 148 800.001999-01-01T00:00:32.251999-01-01T00:00:00.25TIME_WAIT915 148 800.251999-01-01T00:00:32.501999-01-01T00:00:00.50TIME_WAIT915 148 800.501999-01-01T00:00:32.751999-01-01T00:00:00.75TIME_WAIT915 148 800.751999-01-01T00:00:33.001999-01-01T00:00:01.00TIME_WAIT915 148 801.001999-01-01T00:00:33.251999-01-01T00:00:01.25TIME_WAIT915 148 801.25

Az aszinkron Mills-stílusú Unix-idő pontosan kiszámolható a szökőmásodperc állapotát jelző változó figyelembe vételével, mivel ez pontosan jelzi, hogy a szökőmásodpercet beszúrták vagy sem.

A negatív szökőmásodperc esetén, amikor az Unix-idő névlegesen értelmezhetetlen értéket venne fel, a változó TIME_DEL figyelembe vételével pontosan átszámolhatók az idők.

A Mills-féle implementáció mind a pozitív, mind a negatív szökőmásodpercek esetén megsérti a POSIX előírásait, de a szökőmásodperc-változó állapotának figyelembe vételével létre lehet hozni a korrekt POSIX-időt.

TAI-alapú változat Az Unix-idő egyik ritkább változata a Nemzetközi atomidőn (francia neve, a Temps atomique international alapján rövidítése TAI) alapul az UTC helyett. Mivel a TAI rendszerben nincsenek szökőmásodpercek, egy TAI nap pontosan másodpercből áll, vagyis csak és kizárólag az 1970-01-01T00:00:00 TAI óta eltelt másodperceket veszi figyelembe. Az eltelt idő kiszámításához ez sokkal egyszerűbb algoritmust igényel, és a két időpont közt eltelt idő kiszámításában nem lépnek fel olyan problémák, mint az NTP-alapú, vagy a POSIX előírásainak szigorúan megfelelő rendszerekben.

A TAI-alapú változatban szükséges a szökőmásodpercek táblázatát is figyelembe venni az Unix-idő és az UTC közötti konvertálás során, hasonlóan az időzónák táblázatának figyelembevételéhez. Azonban a szökőmásodpercek táblázatát sokkal gyakrabban kell frissíteni, mint az időzóna táblázatot, mivel a szökőmásodpercek beszúrására gyakrabban kerül sor, mint az időszámítás szabályainak változtatására. A két idő közötti konverzió szintén problémás az 1972. előtti dátumok esetében.

A TAI-alapú változat azonban, látszólagos megfelelése ellenére, nem Unix-idő, mivel az időt a POSIX szabványtól jelentősen eltérő értékekkel adja meg és nem lehet egyszerű matematikai egyenlettel megadni az UTC és a TAI-alapú idő közötti kapcsolatot (a szökőmásodperc-táblázatok miatt).

A Unix-idő formátuma A Unix-időt bármilyen, számot megjeleníteni képes formátumban meg lehet adni. Egyes alkalmazások az Unix-időt string formátumban, tízes számrendszerű számjegyek sorozataként reprezentálja. Az Unix-idő bináris formában is kifejezhető.

A szabványos Unix-időt a time t adattípussal kell megadni, amely előjeles egész szám típusú, 32 bit hosszú szám, amely az Unix-időt az előzőekben leírt módon jeleníti meg. Mivel egész szám, csak egész másodpercek megjelenítésére alkalmas, a legtöbb Unix-variáns ezért csak másodperc pontossággal tudja megjeleníteni az időt. Mivel 32 bit hosszú és ebből egy bit az előjel-információ, a time_t csak mintegy 136 évnek megfelelő időtartamot tud kifejezni. A legelső, time_t-ben kifejezhető időpont 1901-12-13T20:45:52Z, míg a legutolsó 2038-01-19T03:14:07Z. Ezt követően a Unix-időnek ez a reprezentálása túlcsordul, ami a 2000. év problémájához hasonló gondokat okozhat.

Egyes operációs rendszerekben a time_t megjelenítésére 64 bitet használnak, amely negatív irányban a világegyetem jelenleg becsült koránál (kb. 13,7 milliárd év) 20-szor hosszabb időtartamot tud kifejezni, míg pozitív irányban a világegyetem várható élettartamánál sokkal hosszabb időt, kb. 293 milliárd évet fejezhet ki, ami gyakorlati szempontok alapján több mint megfelelő.

A time_t korlátjának feloldására az egyik megoldás az előjel elhagyása lenne, amely lényegében megkettőzné a 32 biten kifejezhető időtartamot, viszont ekkor a Unix-idővel nem lehetne 1970 előtti időpontokat kifejezni. Dennis Ritchie szerint, akit megkérdeztek, hogy melyik megoldást választaná, azt válaszolt: jó lenne, ha a Unix-idő az ő élete során minden időt ki tudna fejezni (Ritchie a Unix-idő szerint körül született). A jelenlegi konszenzus szerint az Unix-idő továbbra is előjeles marad.

A POSIX és az Open Group Unix specifikációkban szerepel az ISO C függvénygyűjtemény, amely meghatározza, hogy a time_t aritmetikus típusú legyen, de nem ír elő egy specifikus formátumot.

A nem-egész Unix időt általában kompozit egész számokként ábrázolják, vagyis az első egész rész adja meg a time_t szerint kifejezett Unix-időt, míg a második rész a töredék másodperceket. A tízes számrendszeren alapuló, fixpontos időformátum nagyon egyszerűen alakítható át más formátumokká.

UTC alap A UTC időformátum jelenlegi formájában, a szökőmásodpercekkel együtt, csak 1972. január 1-jén lépett életbe. 1961-től létezett a UTC egyik régebbi formája, amelyben valós számú másodpercekkel számoltak, illetve a UTC másodperc hosszabb is volt, mint az SI-mértékegységrendszerben kifejezett másodperc. 1961 előtt a UTC nem létezett, és 1958 előtt nem is terjedtek el a pontos időszámítást lehetővé tévő atomórák.