Unix időbélyeg átváltása dátummá (és vissza)

Linux 8 perc olvasás

Naplófájlokban, adatbázisokban és API-válaszokban gyakran egy hosszú szám áll a dátum helyén, például 1767225600. Ez a Unix időbélyeg (angolul Unix timestamp vagy epoch time). Ebben a leírásban bemutatjuk, mit jelent, hogyan váltod át olvasható dátummá és vissza Linux szerveren, például egy KVM VPS-en, és mire figyelj az időzónák és az ezredmásodpercek miatt.

Egy-egy érték gyors átváltásához használhatod a böngészőben futó átváltónkat is; a szerveren ugyanezt a lenti parancsokkal végezheted el.

A parancsokat 2026 novemberében AlmaLinux 10.2 (GNU coreutils 9.5, gawk 5.3) és Ubuntu 26.04 (uutils coreutils 0.10, gawk 5.3, mawk 1.3.4) rendszeren, a macOS-es változatokat macOS 26-on próbáltuk ki.

Mi az a Unix időbélyeg?

A Unix időbélyeg az 1970. január 1. 00:00:00 UTC (az „epoch”) óta eltelt másodpercek száma. Néhány fontos tulajdonsága:

  • Nincs időzónája. Ugyanaz a szám ugyanazt a pillanatot jelenti Budapesten, New Yorkban és Tokióban is; időzóna csak akkor kerül a képbe, amikor dátummá alakítod. Az 1767225600 például 2026. január 1. 00:00:00 UTC, ami Budapesten 01:00:00 (CET).
  • A szökőmásodperceket nem számolja. A POSIX szabvány szerint minden nap pontosan 86 400 másodperc, ezért az időbélyeg és a csillagászati idő között néhány másodperc eltérés van, ami a gyakorlatban nem számít.
  • Az 1970 előtti időpontok negatívak: a -1 1969. december 31. 23:59:59 UTC.

Hol találkozhatsz vele? A journalctl -o short-unix kimenetében, az auditnaplóban (/var/log/audit/audit.log, pl. msg=audit(1794162987.503:641)), adatbázisok INT vagy BIGINT oszlopaiban, JSON API-kban, JWT tokenek exp mezőjében és a fájlok módosítási idejénél (stat -c %Y fajl). A naplók olvasásáról a Naplófájlok olvasása Linuxon leírásunkban olvashatsz.

Másodperc, ezredmásodperc vagy mikroszekundum?

Sok rendszer nem másodpercben, hanem finomabb egységben tárolja az időbélyeget. Jelenleg (2286-ig) a számjegyek számából felismerhető, melyikről van szó:

Számjegyek Egység Példa Hol fordul elő
10 másodperc 1767225600 date +%s, PHP time(), MySQL UNIX_TIMESTAMP()
13 ezredmásodperc (ms) 1767225600123 JavaScript Date.now(), Java, sok REST API
16 mikroszekundum (µs) 1767225600123456 egyes naplóformátumok és adatbázisok
19 nanoszekundum (ns) 1767225600123456789 date +%s%N, Go

A leggyakoribb hiba, hogy egy ezredmásodperces értéket másodpercként értelmez a program. A date ilyenkor nem jelez hibát, hanem egy nagyon távoli dátumot ír ki:

date -d @1767225600123
# Thu Feb 25 01:02:03 AM CET 57971

Ilyenkor oszd el az értéket 1000-rel (vagy hagyd le az utolsó három számjegyet), illetve add meg tizedesként:

date -d @$((1767225600123 / 1000))
date -d @1767225600.123 +'%F %T.%3N'
# 2026-01-01 01:00:00.123

A jelenlegi Unix-idő lekérdezése

# Másodpercben
date +%s

# Ezredmásodpercben, illetve nanoszekundumban
date +%s%3N
date +%s%N

# Bash 5-ben külső parancs nélkül is (másodperc, illetve mikroszekundumos pontossággal)
echo $EPOCHSECONDS
echo $EPOCHREALTIME

Időbélyeg átváltása dátummá a date paranccsal

A GNU date a -d (--date) kapcsolóval kapja meg az időpontot; a @ jelzi, hogy Unix időbélyegről van szó:

# A szerver időzónájában
date -d @1767225600
# Thu Jan  1 01:00:00 AM CET 2026

# UTC-ben
date -u -d @1767225600
# Thu Jan  1 12:00:00 AM UTC 2026

# Egy másik időzónában (a szerver beállítását nem változtatja meg)
TZ=America/New_York date -d @1767225600
# Wed Dec 31 07:00:00 PM EST 2025

# ISO 8601 formátumban, időzóna-eltolással
date -d @1767225600 --iso-8601=seconds
# 2026-01-01T01:00:00+01:00

# RFC 5322 (e-mail fejléc) formátumban
date -d @1767225600 -R
# Thu, 01 Jan 2026 01:00:00 +0100

# Saját formátumban
date -d @1767225600 +'%Y-%m-%d %H:%M:%S'
# 2026-01-01 01:00:00

AlmaLinux 10 konzol: a date paranccsal a Unix időbélyeg dátummá alakítása, UTC és ISO 8601 kimenet, dátum átváltása időbélyeggé, egy ezredmásodperces érték hibás értelmezése és egy New York-i időzónás átváltás

A kimenet nyelvét és formáját a nyelvi beállítás (locale) határozza meg. Az AlmaLinux 10 cloud image-én en_US.UTF-8 az alapértelmezés, ezért angol, 12 órás formátumot kapsz. Magyar formátumhoz telepítsd a magyar nyelvi csomagot (sudo dnf install glibc-langpack-hu), és add meg a LC_TIME változót:

LC_TIME=hu_HU.UTF-8 date -d @1767225600
# 2026. jan. 1., csütörtök, 01:00:00 CET

Szkriptekben érdemes saját formátumot (+'%Y-%m-%d %H:%M:%S' vagy +%F %T) használni, mert az nem függ a nyelvi beállítástól.

A Bash beépített printf parancsa is tud időbélyeget formázni, külső program indítása nélkül, ami ciklusokban gyorsabb:

printf '%(%F %T)T\n' 1767225600
# 2026-01-01 01:00:00

Dátum átváltása időbélyeggé

A +%s formátum kiírja a megadott időpont Unix időbélyegét. Időzóna nélkül a date a szerver időzónájában értelmezi a dátumot, ezért ugyanaz a dátum más szerveren más időbélyeget adhat:

# A szerver időzónájában (itt Europe/Budapest)
date -d '2026-11-08 14:30' +%s
# 1794144600

# UTC-ként értelmezve
date -u -d '2026-11-08 14:30' +%s
date -d '2026-11-08 14:30 UTC' +%s
# 1794148200

# Időzóna-eltolással (ISO 8601)
date -d '2026-11-08T14:30:00+01:00' +%s
# 1794144600

# Egy adott időzónában
TZ=Europe/Budapest date -d '2026-11-08 14:30' +%s
date -d 'TZ="America/New_York" 2026-11-08 14:30' +%s
# 1794166200

# Csak dátum: az adott nap 00:00 a szerver időzónájában
date -d '2026-11-08' +%s
# 1794092400

A date relatív időpontokat is megért, ami ütemezett feladatoknál és lejárati idők számításánál hasznos:

date -d 'now + 7 days' +%s
date -d 'tomorrow 00:00' +%s
date -d '+7 days'

Egy fájl módosítási idejét a stat adja meg időbélyegként, a GNU date -r kapcsolója pedig dátumként:

stat -c %Y /etc/hostname
date -r /etc/hostname +%s
date -r /etc/hostname

Időbélyegek átváltása naplófájlokban

Ha egy fájl első oszlopa Unix időbélyeg, az awk strftime() függvényével soronként átválthatod. Példafájl (esemenyek.log):

1767225600 login alice
1767229200 logout alice
1794144600 login bob
# Az első oszlop cseréje olvasható dátumra (a szerver időzónájában)
awk '{ $1 = strftime("%Y-%m-%d %H:%M:%S", $1); print }' esemenyek.log
# 2026-01-01 01:00:00 login alice
# 2026-01-01 02:00:00 logout alice
# 2026-11-08 14:30:00 login bob

# UTC-ben: a harmadik paraméter 1
awk '{ print strftime("%F %T", $1, 1), $2, $3 }' esemenyek.log

# Ezredmásodperces időbélyeg esetén ossz 1000-rel
awk '{ $1 = strftime("%F %T", $1 / 1000); print }' esemenyek-ms.log

A strftime() nem része a POSIX awk szabványnak, de a GNU awk (gawk) és a Debian/Ubuntu mawk 1.3.4-es változata is ismeri: a teszten mindkettő ugyanazt adta. A teszten AlmaLinuxon és Ubuntu 26.04-en is az awk parancs a gawk volt. Ha egy régebbi rendszeren mégsem működne, használj egy while read ciklust:

while read -r ts rest; do
  echo "$(date -d @"$ts" '+%F %T') $rest"
done < esemenyek.log

Ez nagy fájloknál lassabb, mert soronként elindít egy date folyamatot; ilyenkor a printf '%(%F %T)T' gyorsabb.

Néhány eszköz maga is átváltja az időbélyegeket: a journalctl alapból dátumot mutat (az -o short-unix épp fordítva, időbélyeget), az auditnaplóban pedig az ausearch -i kapcsolója írja ki a msg=audit(...) értékeket dátumként. A webszerver-naplók elemzéséről a Web szerver logok elemzése bejegyzésünkben írtunk.

Gyors megfelelők más nyelvekben

PHP

php -r 'echo date("c", 1767225600), PHP_EOL;'
php -r 'echo time(), PHP_EOL;'
php -r 'echo strtotime("2026-11-08 14:30"), PHP_EOL;'

A PHP nem a rendszer, hanem a date.timezone beállítás időzónáját használja, a TZ környezeti változót figyelmen kívül hagyja. AlmaLinux 10-en a parancssori PHP 8.3 alapértelmezése UTC volt, ezért az első parancs 2026-01-01T00:00:00+00:00-t, a strtotime pedig UTC-ként értelmezve 1794148200-at adott. Az időzónát a php.ini fájlban vagy parancsonként adhatod meg:

php -d date.timezone=Europe/Budapest -r 'echo date("c", 1767225600), PHP_EOL;'
# 2026-01-01T01:00:00+01:00

Python

python3 -c 'import time; print(int(time.time()))'
python3 -c 'import datetime as d; print(d.datetime.fromtimestamp(1767225600))'
python3 -c 'import datetime as d; print(d.datetime.fromtimestamp(1767225600, d.timezone.utc).isoformat())'
python3 -c 'import datetime as d; print(int(d.datetime(2026, 11, 8, 14, 30).timestamp()))'

A fromtimestamp() időzóna nélkül a rendszer időzónáját használja (2026-01-01 01:00:00), a d.timezone.utc paraméterrel UTC-t (2026-01-01T00:00:00+00:00).

MySQL és MariaDB

SELECT FROM_UNIXTIME(1767225600);
SELECT FROM_UNIXTIME(1767225600, '%Y.%m.%d %H:%i');
SELECT UNIX_TIMESTAMP('2026-11-08 14:30:00');
SELECT UNIX_TIMESTAMP();

Mindkét függvény a kapcsolat időzónáját (time_zone) használja, amely alapból a szerver rendszeridőzónája (SYSTEM). UTC-hez állítsd be a kapcsolat elején: SET time_zone = '+00:00';. A nevesített időzónák (pl. 'Europe/Budapest') csak az időzóna-táblák betöltése után működnek (mariadb-tzinfo-to-sql), különben Unknown or incorrect time zone hibát kapsz. A MariaDB 10.11 a 2038. január 19. utáni időbélyegekre NULL-t ad vissza (lásd lent). A MariaDB telepítéséről a MariaDB adatbázis-kiszolgáló telepítése leírásban olvashatsz.

JavaScript

Date.now();                                // ezredmásodperc
Math.floor(Date.now() / 1000);             // másodperc
new Date(1767225600 * 1000).toISOString(); // "2026-01-01T00:00:00.000Z"

A JavaScript Date ezredmásodpercben számol, ezért egy másodperces időbélyeget 1000-rel meg kell szorozni, a Date.now() értékét pedig el kell osztani, mielőtt egy szerveroldali programnak átadod.

macOS és BSD: date -r

A macOS és a BSD rendszerek date parancsa másképp működik: a -d @... helyett a -r kapcsoló vár Unix időbélyeget, dátumból pedig a -j -f kapcsolókkal készít időbélyeget:

# macOS / BSD
date -r 1767225600
date -u -r 1767225600 '+%Y-%m-%d %H:%M:%S'
date -j -f '%Y-%m-%d %H:%M:%S' '2026-11-08 14:30:00' +%s

Linuxon (GNU date) a -r egy fájl módosítási idejét írja ki, ezért a date -r 1767225600 ott No such file or directory hibát ad.

Ubuntu 26.04-en a date parancs a Rust nyelven írt uutils coreutils része. A leírásban szereplő GNU date parancsok a teszten ugyanazt az eredményt adták; ha mégis eltérést tapasztalsz, a GNU változat gnudate néven is elérhető.

A 2038-as probléma

A régi rendszerek az időbélyeget előjeles 32 bites egész számként tárolják, amelynek legnagyobb értéke 2147483647, azaz 2038. január 19. 03:14:07 UTC. Egy másodperccel később a szám átfordul, és a dátum 1901. december 13. lesz.

A 64 bites Linux rendszerek és a date parancs már nem érintettek (date -u -d @2147483648 gond nélkül 2038. január 19. 03:14:08-at ír ki), a probléma inkább régi, 32 bites programokban és adatbázisokban marad meg:

  • az INT típusú oszlopok, amelyekben időbélyeget tárolnak: helyette használj BIGINT-et vagy DATETIME-ot;
  • a MySQL és MariaDB TIMESTAMP oszloptípusa, amely 2038-ig tárol dátumot; a teszten a MariaDB 10.11 FROM_UNIXTIME(2147483648) hívása is NULL-t adott. A dokumentáció szerint a MariaDB 11.5-től a 64 bites rendszereken a TIMESTAMP és ezek a függvények 2106-ig működnek; a MySQL 8.0.28-tól a FROM_UNIXTIME() és a UNIX_TIMESTAMP() 3001-ig, a TIMESTAMP oszloptípus viszont továbbra is csak 2038-ig.

Időzóna és pontos idő a szerveren

Az átváltás csak akkor ad helyes eredményt, ha a szerver órája pontos, és az időzónája a várt érték. Ellenőrzéséről és beállításáról a Hostname, időzóna és időszinkron beállítása leírásunk szól. Az ütemezett feladatok is a szerver helyi idejében futnak, erről a Crontab szintaxis és ütemezett feladatok Linuxon cikkben olvashatsz.

Vissza: Linux leírások (76)