Dvě vrstvy kódování tvoří unixový čas. První vrstva kóduje časový bod jako skalární reálné číslo, které představuje počet sekund, které uplynuly od 00:00:00 UTC čtvrtka 1. ledna 1970. Druhá vrstva kóduje toto číslo jako posloupnost bitů nebo desítkových číslic.
Jak je u UTC standardem, tento článek označuje dny pomocí gregoriánského kalendáře a počítá časy v rámci každého dne v hodinách, minutách a sekundách. V některých příkladech je uveden také mezinárodní atomový čas (TAI), další časové schéma, které používá stejné sekundy a zobrazuje se ve stejném formátu jako UTC, ale v němž je každý den dlouhý přesně 86400 sekund a postupně ztrácí synchronizaci s otáčením Země rychlostí zhruba jedné sekundy za rok.
Kódování času jako číslaUpravit
Unixový čas je jedno znaménkové číslo, které se každou sekundu zvětšuje, což počítačům usnadňuje jeho ukládání a manipulaci než běžné systémy dat. Interpretační programy jej pak mohou převést do lidsky čitelného formátu.
Epocha Unixu je čas 00:00:00 UTC 1. ledna 1970. S touto definicí je problém v tom, že UTC neexistoval ve své současné podobě až do roku 1972; tento problém je diskutován níže. Pro stručnost se ve zbytku této části používá formát data a času ISO 8601, ve kterém je epocha Unixu 1970-01-01T00:00:00Z.
Číslo času Unixu je v epoše Unixu nulové a od epochy se zvyšuje přesně o 86400 za den. Tedy 2004-09-16T00:00:00Z, 12677 dní po epoše, je reprezentováno číslem času Unix 12677 × 86400 = 1095292800. Tento postup lze rozšířit i zpětně od epochy pomocí záporných čísel, takže 1957-10-04T00:00:00Z, 4472 dní před epochou, je reprezentováno číslem času Unix -4472 × 86400 = -386380800. To platí i v rámci dnů; časové číslo v libovolné denní době je počet sekund, které uplynuly od půlnoci začínající tento den, přičtený k časovému číslu této půlnoci.
Protože čas Unixu je založen na epoše a kvůli běžnému nedorozumění, že epocha Unixu je jediná epocha (často nazývaná „epocha“ ), je čas Unixu někdy označován jako epochový čas.
Přestupné sekundyEdit
Výše uvedené schéma znamená, že v běžném dni UTC, který má trvání 86400 sekund, se číslo času Unixu přes půlnoc průběžně mění. Například na konci dne použitého ve výše uvedených příkladech probíhá reprezentace času takto:
Pokud nastane přestupná sekunda, den UTC netrvá přesně 86400 sekund a časové číslo systému Unix (které se každý den vždy zvyšuje přesně o 86400) zažívá diskontinuitu. Přestupná sekunda může být kladná nebo záporná. Žádná záporná přestupná sekunda nebyla nikdy vyhlášena, ale pokud by se tak stalo, pak by na konci dne se zápornou přestupnou sekundou časové číslo systému Unix poskočilo o 1 na začátek následujícího dne. Při kladné přestupné sekundě na konci dne, ke které dochází v průměru přibližně jednou za rok a půl, se časové číslo systému Unix během přestupné sekundy plynule zvyšuje do dalšího dne a na konci přestupné sekundy skočí zpět o 1 (vrátí se na začátek dalšího dne). Například toto se stalo na systémech striktně vyhovujících standardu POSIX.1 na konci roku 1998:
Čísla času v systému Unix se opakují ve vteřině bezprostředně následující po kladné přestupné sekundě. Unixové časové číslo 1483142400 je tedy nejednoznačné: může odkazovat buď na začátek přestupné sekundy (2016-12-31 23:59:60), nebo na její konec o sekundu později (2017-01-01 00:00:00). V teoretickém případě, kdy nastane záporná přestupná sekunda, k žádné nejednoznačnosti nedochází, ale místo toho existuje řada čísel unixového času, která neodkazují vůbec na žádný bod v čase UTC.
Unixové hodiny jsou často implementovány s jiným typem manipulace s kladnou přestupnou sekundou spojenou s protokolem NTP (Network Time Protocol). Výsledkem je systém, který neodpovídá standardu POSIX. Podrobnosti naleznete v následující části týkající se NTP.
Při práci s periodami, které nezahrnují přestupnou sekundu UTC, je rozdíl mezi dvěma časovými čísly Unixu roven trvání periody v sekundách mezi odpovídajícími časovými body. Jedná se o běžnou výpočetní techniku. Tam, kde se vyskytují přestupné sekundy, však takové výpočty dávají špatnou odpověď. V aplikacích, kde je vyžadována tato úroveň přesnosti, je nutné při práci s časy Unix nahlížet do tabulky přestupných sekund a často je vhodnější použít jiné kódování času, které tímto problémem netrpí.
Číslo času Unix se snadno převede zpět na čas UTC tak, že se vezme kvocient a modul čísla času Unix, modulo 86400. Kvocient je počet dní od epochy a modul je počet sekund od půlnoci UTC daného dne. Pokud je zadáno číslo času Unix, které je nejednoznačné z důvodu kladné přestupné sekundy, interpretuje jej tento algoritmus jako čas těsně po půlnoci. Nikdy negeneruje čas, který je během přestupné sekundy. Je-li zadáno číslo času Unix, které je neplatné kvůli záporné přestupné sekundě, vygeneruje stejně neplatný čas UTC. Pokud jsou tyto podmínky významné, je k jejich zjištění nutné nahlédnout do tabulky přestupných sekund.
Nesynchronní varianta založená na protokolu síťového časuUpravit
Obvykle jsou implementovány unixové hodiny ve stylu Mills s obsluhou přestupných sekund, která není synchronní se změnou čísla unixového času. Časové číslo se zpočátku sníží v místě, kde mělo dojít k přestupu, a poté přeskočí na správný čas 1 sekundu po přestupu. To usnadňuje implementaci a je popsáno v Millsově článku. Toto se děje přes kladnou přestupnou sekundu:
Tu lze správně dekódovat, věnujeme-li pozornost stavové proměnné přestupná sekunda, která jednoznačně udává, zda byl přestup již proveden. Změna stavové proměnné je synchronní se skokem.
Podobná situace nastává při záporné přestupné sekundě, kdy je přeskočená sekunda mírně opožděná. Velmi krátce systém ukazuje nominálně nemožné časové číslo, ale to lze zjistit pomocí stavu TIME_DEL a opravit.
V tomto typu systému porušuje unixové časové číslo POSIX kolem obou typů přestupných sekund. Shromažďování stavové proměnné přestupné sekundy spolu s časovým číslem umožňuje jednoznačné dekódování, takže v případě potřeby lze vygenerovat správné časové číslo POSIX nebo uložit plný čas UTC ve vhodnějším formátu.
Dekódovací logika potřebná pro zvládnutí tohoto stylu unixových hodin by také správně dekódovala hypotetické hodiny splňující POSIX pomocí stejného rozhraní. Toho by bylo dosaženo indikací stavu TIME_INS během celé vložené přestupné sekundy a následnou indikací TIME_WAIT během celé následující sekundy při opakovaném počítání sekund. To vyžaduje synchronní zpracování přestupných sekund. To je pravděpodobně nejlepší způsob, jak vyjádřit čas UTC ve formě unixových hodin prostřednictvím unixového rozhraní, když základní hodiny přestupné sekundy zásadně neovlivňují.
Varianta založená na TAIUpravit
Další, mnohem vzácnější, nevyhovující varianta unixového měření času zahrnuje kódování TAI namísto UTC; některé systémy Linux jsou takto nakonfigurovány. Protože TAI nemá přestupné sekundy a každý den TAI má přesně 86400 sekund, je toto kódování vlastně čistě lineárním počítáním sekund uplynulých od 1970-01-01T00:00:00 TAI. Díky tomu je aritmetika časových intervalů mnohem jednodušší. Hodnoty času z těchto systémů netrpí nejednoznačností, kterou mají přísně vyhovující systémy POSIX nebo systémy řízené NTP.
V těchto systémech je pro správný převod mezi UTC a pseudounixovou reprezentací času nutné nahlédnout do tabulky přestupných sekund. To se podobá způsobu, jakým je třeba konzultovat tabulky časových pásem pro převod na občanský čas a z něj; databáze časových pásem IANA obsahuje informace o přestupných sekundách a vzorový kód dostupný ze stejného zdroje tyto informace používá pro převod mezi časovými značkami založenými na TAI a místním časem. Převod také naráží na definiční problémy před rokem 1972, kdy začala platit současná podoba UTC (viz níže část Základ UTC).
Tento systém založený na TAI navzdory své povrchní podobnosti není unixovým časem. Kóduje časy s hodnotami, které se od hodnot času POSIX liší o několik sekund. Verze tohoto systému byla navržena k začlenění do souboru ISO C time.h
, ale v roce 2011 byla přijata pouze část UTC. Soubor tai_clock
však existuje v jazyce C++20.
Reprezentace číslaUpravit
Číslo unixového času lze reprezentovat v libovolné formě schopné reprezentovat čísla. V některých aplikacích je číslo jednoduše reprezentováno textově jako řetězec desetinných číslic, což vyvolává jen triviální dodatečné problémy. Některé binární reprezentace unixových časů jsou však obzvláště významné.
Unixový datový typ time_t
, který reprezentuje časový bod, je na mnoha platformách celé číslo se znaménkem, tradičně o 32 bitech (viz však níže), přímo kódující unixové časové číslo, jak je popsáno v předchozí části. To, že je 32bitový, znamená, že pokrývá rozsah celkem asi 136 let. Minimální reprezentovatelné datum je pátek 1901-12-13 a maximální reprezentovatelné datum je úterý 2038-01-19. Jednu sekundu po 03:14:07 UTC 2038-01-19 tato reprezentace přeteče. Tento milník je očekáván se směsicí pobavení a strachu – viz problém roku 2038.
V některých novějších operačních systémech je time_t
rozšířen na 64 bitů. Tím se reprezentovatelné časy rozšíří přibližně o 293 miliard let v obou směrech, což je více než dvacetinásobek současného stáří vesmíru v každém směru.
Původně se vedly spory o to, zda má být unixový time_t
podepsaný nebo nepodepsaný. Pokud by byl bez znaménka, jeho rozsah by se v budoucnu zdvojnásobil, což by oddálilo přetečení 32 bitů (o 68 let). Pak by však nebyl schopen reprezentovat časy před epochou. Shoda panuje na tom, že time_t
má být se znaménkem, a to je obvyklá praxe. Softwarová vývojová platforma pro verzi 6 operačního systému QNX má nepodepsaný 32bitový time_t
, ačkoli starší verze používaly podepsaný typ.
Specifikace POSIX a Open Group Unix obsahují standardní knihovnu C, která obsahuje časové typy a funkce definované v hlavičkovém souboru <time.h>
. Standard ISO C uvádí, že time_t
musí být aritmetický typ, ale nepředepisuje pro něj žádný konkrétní typ ani kódování. POSIX vyžaduje, aby time_t
byl celočíselný typ, ale nepřikazuje, aby byl podepsaný nebo nepodepsaný.
Unix nemá tradici přímé reprezentace neceločíselných unixových časových čísel jako binárních zlomků. Místo toho jsou časy s přesností pod sekundou reprezentovány pomocí složených datových typů, které se skládají ze dvou celých čísel, z nichž první je time_t
(integrální část unixového času) a druhé je zlomková část časového čísla v miliontinách (v struct timeval
) nebo miliardtinách (v struct timespec
). Tyto struktury poskytují formát dat s pevnou desetinnou čárkou, který je užitečný pro některé aplikace a triviální pro převod pro jiné.
Základ UTCEdit
Současná podoba UTC s přestupnými sekundami je definována až od 1. ledna 1972. Předtím, od 1. ledna 1961, existovala starší forma UTC, ve které nejenže existovaly občasné časové kroky, které byly o necelé počty sekund, ale také sekunda UTC byla o něco delší než sekunda SI a periodicky se měnila, aby se průběžně přibližovala rotaci Země. Před rokem 1961 neexistovalo žádné UTC a před rokem 1958 nebylo rozšířené atomové měření času; v těchto obdobích se místo atomové časové stupnice používala určitá aproximace GMT (založená přímo na rotaci Země).
Přesná definice unixového času jako kódování UTC je nesporná pouze při aplikaci na současnou podobu UTC. Epocha Unixu předcházející začátku této formy UTC nemá vliv na její použití v této době: počet dní od 1. ledna 1970 (epocha Unixu) do 1. ledna 1972 (začátek UTC) není sporný a počet dní je vše, co je pro čas Unixu podstatné.
Význam hodnot času Unixu pod +63072000 (tj. před 1. lednem 1972) není přesně definován. Základem těchto unixových časů je nejlépe chápat jako blíže neurčenou aproximaci UTC. Počítače té doby měly jen zřídkakdy hodiny nastaveny dostatečně přesně, aby v každém případě poskytovaly smysluplné subsekundové časové značky. Unixový čas není vhodným způsobem reprezentace časů před rokem 1972 v aplikacích vyžadujících subsekundovou přesnost; takové aplikace musí přinejmenším definovat, jakou formu UT nebo GMT používají.
Od roku 2009 se zvažuje možnost ukončení používání přestupných sekund v civilním čase. Pravděpodobným prostředkem k provedení této změny je definování nové časové stupnice, nazývané mezinárodní čas, která se zpočátku shoduje s UTC, ale poté nemá přestupné sekundy a zůstává tak s konstantním posunem od TAI. Pokud k tomu dojde, je pravděpodobné, že čas Unixu bude výhledově definován podle této nové časové stupnice namísto UTC. Nejistota, zda k tomu dojde, nečiní výhledový čas Unixu méně předvídatelným, než je nyní: kdyby UTC jednoduše neměl žádné další přestupné sekundy, výsledek by byl stejný.