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/25 ir 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ātsVienībaPiemērs
Unix (POSIX)Sekundes1711929600
JavaScript Date.now()Milisekundes1711929600000
Python time.time()Sekundes (peldošais)1711929600.123
Datubāzu laika zīmogiBieži mikrosekundes1711929600000000

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

KasSekundes
1 minūte60
1 stunda3,600
1 diena86,400
1 nedēļa604,800
30 dienas2,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.