Kas ir Unix laika zīmogs (un kāpēc izstrādātāji to izmanto)?
Unix laika zīmogs ir viens vesels skaitlis: sekunžu skaits, kas pagājis kopš 1970. gada 1. janvāra plkst. 00:00:00 UTC. Šo brīdi sauc par Unix epohu, un kopš tā laika katra sekunde tiek skaitīta nepārtraukti.
Pašreizējais laika zīmogs ir kaut kur ap 1,750,000,000. Ar šo vienu skaitli jebkurš dators, datubāze vai API precīzi zina, kuru brīdi jūs domājat — bez divdomības.
Kāpēc tieši 1970. gads?
Unix tika izstrādāts 1960. gadu beigās Bell Labs. Kad inženieriem vajadzēja fiksētu atskaites punktu laikam, viņi izvēlējās 1970. gada 1. janvāri — jaunas desmitgades sākumu, viegli saprotamu, un pietiekami tuvu pagātnē, lai tajā laikā praktiskajiem datumiem nevajadzētu negatīvus skaitļus.
Tā bija pragmatiska, nevis “ideāla” izvēle. Un tā iesakņojās.
Kādu problēmu Unix laika zīmogi atrisina
Datumu attēlošana kā cilvēkiem lasāmas virknes rada neskaidrības katrā slānī:
- Formāta domstarpības: vai
03/04/25ir 4. marts vai 3. aprīlis? Vai 1925 vai 2025? - Laika joslu juceklis: “piektdien 15:00” ir cits brīdis Londonā nekā Tokijā
- Lokāles atšķirības: vienurīt raksta diena–mēnesis–gads, citur mēnesis–diena–gads
Unix laika zīmogs to apiet. 1711929600 ir viens, nepārprotams laika brīdis neatkarīgi no tā, kur jūs esat un kādu formātu dodat priekšroku. Mašīnas vienojas; cilvēki pēc tam var pārvērst.
Sekundes, milisekundes un mikrosekundes
Sākotnējais Unix laika zīmogs ir sekundēs. Taču dažādas sistēmas izmanto dažādu precizitāti:
| Formāts | Vienība | Piemērs |
|---|---|---|
| Unix (POSIX) | Sekundes | 1711929600 |
JavaScript Date.now() | Milisekundes | 1711929600000 |
Python time.time() | Sekundes (peldošais) | 1711929600.123 |
| Datubāzu laika zīmogi | Bieži mikrosekundes | 1711929600000000 |
Tas ir viens no biežākajiem kļūdu avotiem, strādājot starp sistēmām. Ja JavaScript laika zīmogu tieši nodod Python vai Go funkcijai, tas būs 1,000× par lielu. Vienmēr pārbaudiet precizitāti, šķērsojot sistēmu robežas.
Unix laika zīmogu lasīšana un rakstīšana
JavaScript / TypeScript
// Pašreizējais laika zīmogs sekundēs
Math.floor(Date.now() / 1000)
// Pašreizējais laika zīmogs milisekundēs
Date.now()
// Pārvērst laika zīmogu (sekundes) par Date objektu
new Date(timestamp * 1000)
// Pārvērst Date par laika zīmogu (sekundes)
Math.floor(new Date('2024-04-01').getTime() / 1000)
Python
import time, datetime
# Pašreizējais laika zīmogs (float)
time.time()
# Pārvērst uz datetime
datetime.datetime.fromtimestamp(1711929600)
# Pārvērst datetime uz laika zīmogu
datetime.datetime(2024, 4, 1).timestamp()
SQL (PostgreSQL)
-- Pašreizējais laika zīmogs
EXTRACT(EPOCH FROM NOW())::int
-- Pārvērst uz timestamp
TO_TIMESTAMP(1711929600)
Laika joslas neietekmē pašu laika zīmogu
Tas ir svarīgi un bieži tiek pārprasts.
Unix laika zīmogs vienmēr apzīmē brīdi UTC laikā. Kad jūs to attēlojat, jūs to pārvēršat lokālajā laika joslā. Kad jūs to glabājat, jūs glabājat UTC vērtību. Pats laika zīmogs ir neitrāls pret laika joslām.
Tas nozīmē:
- Divi lietotāji dažādās laika joslās, saglabājot “tagad”, iegūs to pašu laika zīmogu
- Attēlojot, katrs lietotājs to redzēs savā lokālajā laikā
- Datubāzē nav jālabo nobīdes — tikai prezentācijas slānī
2038. gada problēma
Unix laika zīmogi, kas glabāti 32 bitu parakstītā vesela skaitļa formātā, var skaitīt tikai līdz 2,147,483,647 sekundēm — tas atbilst 2038. gada 19. janvārim plkst. 03:14:07 UTC. Pēc tam 32 bitu skaitītājs “apgriežas” uz lielu negatīvu skaitli.
Sistēmas, kas vēl joprojām glabā laika zīmogus kā 32 bitu integerus, tajā datumā salūzīs. Lielākā daļa mūsdienu sistēmu izmanto 64 bitu integerus, kas pārnes pārpildi uz 292 miljardu gadu — praktiski neaktuāli.
Ja strādājat ar iebūvētām sistēmām, mantotām datubāzēm vai vecu C kodu, ir vērts pārbaudīt, kā tiek glabāti laika zīmogi.
Kad izmantot Unix laika zīmogu
Izmantojiet Unix laika zīmogu, ja:
- Glabājat datumus datubāzē un vēlaties vienkāršu, kārtojamu integeru
- Nododat datumus starp sistēmām vai API
- Salīdzināt vai kārtot notikumus hronoloģiski
- Aprēķināt ilgumus (vienkārši atņemiet divus laika zīmogus)
- Strādājat ar kešatmiņu vai derīguma termiņiem (
expires_at = now + 3600)
Izmantojiet formatētu datuma virkni, ja:
- Rādāt datumu lietotājam
- Žurnalējat (log) cilvēkiem lasāmus notikumus
- Strādājat izklājlapās vai CSV eksportos
Ātrās konversijas
| Kas | Sekundes |
|---|---|
| 1 minūte | 60 |
| 1 stunda | 3,600 |
| 1 diena | 86,400 |
| 1 nedēļa | 604,800 |
| 30 dienas | 2,592,000 |
| 1 gads (aptuveni) | 31,536,000 |
Unix laika zīmogu konvertētājs momentā pārvērš jebkuru laika zīmogu cilvēkiem lasāmā datumā vai pārveido datumu par Unix laika zīmogu.