Unix-idő

A Wikipédiából, a szabad enciklopédiából
Jump to navigation Jump to search

A Unix-idő vagy POSIX idő a számítástechnikában a UTC szerinti 1970. január 1. éjfél ó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ó[szerkesztés]

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á[szerkesztés]

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 86 400 másodperc, de 86 401 vagy 86 399 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 86 400 másodperccel nő, így például 2004-09-16T00:00:00Z, ami 12 677 nappal a Unix epoch után van, Unix-időben 12 677 × 86 400 = 1 095 292 800. 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 × 86 400 = −386 380 800.

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 64 543,54 másodperccel van éjfél után, Unix-időben 1 095 292 800 + 64 543,54 = 1 095 357 343,53999996. 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 (86 400 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 napon
TAI UTC Unix-idő
2004-09-17T00:00:30.75 2004-09-16T23:59:58.75 1 095 379 198,75
2004-09-17T00:00:31.00 2004-09-16T23:59:59.00 1 095 379 199
2004-09-17T00:00:31.25 2004-09-16T23:59:59.25 1 095 379 199,25
2004-09-17T00:00:31.50 2004-09-16T23:59:59.50 1 095 379 199,5
2004-09-17T00:00:31.75 2004-09-16T23:59:59.75 1 095 379 199,75
2004-09-17T00:00:32.00 2004-09-17T00:00:00.00 1 095 379 200
2004-09-17T00:00:32.25 2004-09-17T00:00:00.25 1 095 379 200,25
2004-09-17T00:00:32.50 2004-09-17T00:00:00.50 1 095 379 200,5
2004-09-17T00:00:32.75 2004-09-17T00:00:00.75 1 095 379 200,75
2004-09-17T00:00:33.00 2004-09-17T00:00:01.00 1 095 379 201
2004-09-17T00:00:33.25 2004-09-17T00:00:01.25 1 095 379 201,25

Ha a UTC nap egy szökőmásodperc miatt nem pontosan 86 400 másodperc hosszú, a Unix-időben egy szakadás lép fel. A Unix idő pontosan 86 400-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ásodpercet
TAI UTC Unix-idő
1999-01-01T00:00:29.75 1998-12-31T23:59:58.75 915 148 798.75
1999-01-01T00:00:30.00 1998-12-31T23:59:59.00 915 148 799.00
1999-01-01T00:00:30.25 1998-12-31T23:59:59.25 915 148 799.25
1999-01-01T00:00:30.50 1998-12-31T23:59:59.50 915 148 799.50
1999-01-01T00:00:30.75 1998-12-31T23:59:59.75 915 148 799.75
1999-01-01T00:00:31.00 1998-12-31T23:59:60.00 915 148 800.00
1999-01-01T00:00:31.25 1998-12-31T23:59:60.25 915 148 800.25
1999-01-01T00:00:31.50 1998-12-31T23:59:60.50 915 148 800.50
1999-01-01T00:00:31.75 1998-12-31T23:59:60.75 915 148 800.75
1999-01-01T00:00:32.00 1999-01-01T00:00:00.00 915 148 800.00
1999-01-01T00:00:32.25 1999-01-01T00:00:00.25 915 148 800.25
1999-01-01T00:00:32.50 1999-01-01T00:00:00.50 915 148 800.50
1999-01-01T00:00:32.75 1999-01-01T00:00:00.75 915 148 800.75
1999-01-01T00:00:33.00 1999-01-01T00:00:01.00 915 148 801.00
1999-01-01T00:00:33.25 1999-01-01T00:00:01.25 915 148 801.25

Mint látható, a 915 148 800,5 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 Protocol-t 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 86400-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[szerkesztés]

Á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 be
TAI UTC állapot Unix-idő
1999-01-01T00:00:29.75 1998-12-31T23:59:58.75 TIME_INS 915 148 798.75
1999-01-01T00:00:30.00 1998-12-31T23:59:59.00 TIME_INS 915 148 799.00
1999-01-01T00:00:30.25 1998-12-31T23:59:59.25 TIME_INS 915 148 799.25
1999-01-01T00:00:30.50 1998-12-31T23:59:59.50 TIME_INS 915 148 799.50
1999-01-01T00:00:30.75 1998-12-31T23:59:59.75 TIME_INS 915 148 799.75
1999-01-01T00:00:31.00 1998-12-31T23:59:60.00 TIME_INS 915 148 800.00
1999-01-01T00:00:31.25 1998-12-31T23:59:60.25 TIME_OOP 915 148 799.25
1999-01-01T00:00:31.50 1998-12-31T23:59:60.50 TIME_OOP 915 148 799.50
1999-01-01T00:00:31.75 1998-12-31T23:59:60.75 TIME_OOP 915 148 799.75
1999-01-01T00:00:32.00 1999-01-01T00:00:00.00 TIME_OOP 915 148 800.00
1999-01-01T00:00:32.25 1999-01-01T00:00:00.25 TIME_WAIT 915 148 800.25
1999-01-01T00:00:32.50 1999-01-01T00:00:00.50 TIME_WAIT 915 148 800.50
1999-01-01T00:00:32.75 1999-01-01T00:00:00.75 TIME_WAIT 915 148 800.75
1999-01-01T00:00:33.00 1999-01-01T00:00:01.00 TIME_WAIT 915 148 801.00
1999-01-01T00:00:33.25 1999-01-01T00:00:01.25 TIME_WAIT 915 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[szerkesztés]

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 86 400 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[szerkesztés]

Az 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én 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 az 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 kfejezhető időtartamot, viszont ekkor az 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 az Unix-idő az ő élete során minden időt ki tudna fejezni (Ritchie az Unix-idő szerint −893 400 000 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, vagyik 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[szerkesztés]

Az 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 az UTC egyik régebbi formája, amelyben valós számú másodpercekkel számoltak, illetve az UTC másodperc hosszabb is volt, mint az SI mértékegység-rendszerben kifejezett másodperc. 1961 előtt az 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.

Ennek megfelelően az Unix-idő definíciója, azaz a UTC szerinti 1970. január 1. éjfél óta eltelt másodpercek száma, csak 1972 után használható problémák nélkül. Szerencsére az Unix epoch kezdete (1970. január 1.) és az UTC jelenlegi változatában életbe lépteése (1972. január 1.) között eltelt napok (másodpercek) száma ismert, ezért a két dátum közötti eltérés nem szignifikáns.

Azonban a 63 072 000 Unix-idő előtti értékek jelentése nem tisztázott pontosan. Ezen értékek alapja a GMT idő valamilyen formájú becslése. Szerencsére abban az időben a legtöbb számítógépnek nem volt olyan belső órája, amely a másodperc tört értékét is feltüntető időbélyegzőt tudott volna létrehozni, ezért a másodperc alapú Unix-idő jó közelítéssel felfogható az 1972 előtti időpontok reprezentálására.

2004 óta felmerült, hogy a jelenlegi szökőmásodpercek rendszerét elhagynák az ún. Nemzetközi Időszámítás (International Time) rendszerében. Az IT rendszer kezdetben megfelelne az UTC-nek, de később úgy módosítanák, hogy ne legyen szükséges szökőmásodperceket bevezetni, vagyis az IT megfelelne a TAI-változatak.

Az Unix-idő története[szerkesztés]

Az Unix-idő első változatai előjel nélküli 32 bites egész számként adták meg az időt, amely a korabeli számítógépek rendszeróráján alapult. Az eredeti Unix epoch ekkor még - az 1971. november 3-án kiadott Unix Programmer's Manual első kiadása alapján az Unix-idő 1971. január 1. 00:00:00 óta eltelt idő, a másodperc 60-ad része alapján számolva. Mivel a 32 biten kifejezett idő tizedmásodpercek alapján csak mintegy 2,5 évet biztosított, az epochot később újradefiniálták, másodpercekben fejezve ki az Unix-időt, amely (az előjelezés bevezetése után) kb. 130 évre növelte az Unix-idővel kifejezhető időtartamot (ld. 2038-probléma).

Az Unix-idő az első meghatározás alapján az epoch óta eltelt idő szimpla, lineáris reprezentációja volt, amely azonban nem vette figyelembe az időszámítást, az első változatban még az időzónát sem határozták meg. Számos későbbi probléma, többek között az Unix-idő jelenlegi bonyolult definíciója abból ered, hogy a gyakorlatban, apránként határozták meg a fogalmát, ahelyett, hogy egy jól kialakított definícióra építették volna az Unix-időt.

Amikor az 1980-as években a POSIX.1-et írták (1988-ban jelent meg), felmerült a kérdés, hogyan lehetne a time_t-t pontosan meghatározni a szökőmásodpercek figyelembe vételével. Az egyik lehetőség volt, hogy az Unix-idő csak lineáris módon reprezentálná az epoch óta eltelt időt, ami egyszerű megoldást jelent, de nem teszi lehetővé az Unix-idő egyszerű átváltását az UTC-re (vagy más polgári időszámítás szerinti időre). A második megoldás az egyszerű átváltás volt, a szökőmásodpercek figyelembe vétele körüli bizonytalanságokkal. A POSIX-bizottság végül az egyszerű megoldást választotta és az Unix-időt az UTC elemeinek megfelelően definiálta.

A POSIX 2001-es felülvizsgálata során orvosolták a korábbi definíció hibáit (pl. 2100-at is szökőévnek vette), de az Unix-időt továbbra is az UTC alapján határozták meg, lineáris idő helyett. A POSIX 2004-es kiadása már több időskálát tett elérhetővé az alkalmazások számára, amelyek megfelelnek az Unix-idő tradicionális felhasználásának. A jövőben várhatóan különféle címkék jelzik majd, hogy melyik skála milyen célra használható. A cikkben leírt Unix-idő, bár még évtizedekig használják majd, feltehetően egyre inkább elavultnak fog számítani, és a korábbinál jobban definiált időszámítási rendszerek fogják felváltani.

time_t partik[forrás?][szerkesztés]

A Unix-hívők számos alkalommal tartottak már ún. time_t partit, amikor az Unix-idő valamelyik jelentősebb értékét ünnepelték. Ezek az alkalmak hasonlítanak a szilveszteri mulatságokra, de persze nem esnek egybe azzal. A time_t partikat általában az Unix-idő valamelyik jelentősebb mérföldköve köré szervezik.

  • 2001. szeptember 9-én UTC 01:46:40-kor ünnepelték az Unix-idő szerint 1 000 000 000-t.
  • 2005. március 18-án UTC 01:58:31-kor volt az Unix-idő 1 111 111 111.
  • 2009. február 13-án UTC 23:31:30-kor érte el az Unix-idő az 1 234 567 890 másodpercet.
  • 2033. május 18-án UTC 03:33:20-kor lesz az Unix-idő 2 000 000 000.

Lásd még[szerkesztés]

Külső hivatkozások[szerkesztés]