Penjelasan Timestamp Unix
Timestamp Unix adalah satu angka yang mewakili suatu momen dalam waktu. Angka ini mudah disimpan dan dibandingkan, tetapi satuan, zona waktu, dan format teks menyebabkan banyak kesalahan konversi.
Apa Itu Waktu Unix
Waktu Unix (disebut juga epoch time atau POSIX time) menghitung detik sejak 1970-01-01 00:00:00 UTC, yaitu epoch Unix. 0 adalah epoch itu sendiri, 1700000000 adalah 2023-11-14 22:13:20 UTC, dan nilai negatif adalah momen sebelum 1970: -1 adalah 1969-12-31 23:59:59 UTC.
Angka ini tidak mengandung zona waktu: angka yang sama menggambarkan momen yang sama di mana pun, sehingga praktis untuk menyimpan, mengurutkan, dan membandingkan peristiwa.
Waktu Unix mengabaikan detik kabisat: setiap hari memiliki tepat 86.400 detik. Saat detik kabisat ditambahkan ke UTC, sistem mengulang satu detik atau menyebarkannya ke periode yang lebih panjang ("smearing"), sehingga selisih waktu yang melewati detik kabisat satu detik lebih pendek daripada waktu yang secara fisik telah berlalu.
Detik, Milidetik, Mikrodetik, atau Nanodetik?
Banyak sistem menghitung dalam satuan yang lebih kecil, dan angkanya sendiri tidak menunjukkan satuannya. Momen yang sama dapat muncul sebagai empat angka yang sangat berbeda:
| Satuan | 2023-11-14 22:13:20 UTC | Jumlah digit (2001–2286) | Sering ditemukan di |
|---|---|---|---|
| Detik | 1700000000 | 10 | date +%s, banyak API, klaim exp JWT |
| Milidetik | 1700000000000 | 13 | JavaScript Date.now() dan Java System.currentTimeMillis() |
| Mikrodetik | 1700000000000000 | 16 | Sebagian database dan sistem logging |
| Nanodetik | 1700000000000000000 | 19 | Go UnixNano() dan Python time.time_ns() |
Menghitung digit adalah cara tercepat untuk memeriksa tanggal masa kini. Konverter LeedyBox menggunakan ide yang sama: nilai hingga 1011 dibaca sebagai detik, hingga 1014 sebagai milidetik, hingga 1017 sebagai mikrodetik, dan nilai yang lebih besar sebagai nanodetik. Aturan praktis ini tidak berlaku untuk tanggal yang jauh dari hari ini, jadi periksa satuannya jika hasilnya tampak aneh.
Presisi juga penting. Angka JavaScript hanya merepresentasikan bilangan bulat secara persis hingga 253 (sekitar 9 × 1015), sehingga nilai nanodetik seperti 1700000000123456789 kehilangan digit terakhirnya saat diurai sebagai angka biasa. Simpan nilai seperti itu sebagai string atau gunakan BigInt; konverter melakukannya secara internal. Untuk membaca klaim exp sebuah token, dekode token tersebut dengan alat Base64 / URL / JWT.
Zona Waktu dan Waktu Musim Panas (DST)
Untuk menampilkan timestamp sebagai tanggal dan jam, Anda memerlukan zona waktu. UTC adalah acuannya; waktu lokal menambahkan selisih (offset) seperti +09:00 di Seoul atau −05:00 di New York pada musim dingin.
Utamakan nama zona waktu IANA seperti Asia/Seoul atau America/New_York daripada offset tetap dan singkatan: nama zona membawa riwayat zona tersebut beserta aturan waktu musim panasnya, sedangkan singkatan seperti CST dapat berarti beberapa zona. Aturan-aturan ini berasal dari database zona waktu, yang berubah beberapa kali dalam setahun, dan browser, sistem operasi, serta bahasa pemrograman menyertakan salinannya sendiri, sehingga hasil untuk tanggal di masa lalu atau masa depan dapat berbeda.
Waktu musim panas menimbulkan dua kasus yang merepotkan saat Anda mengonversi waktu lokal menjadi timestamp:
- Celah (gap): saat jam dimajukan, sebagian waktu lokal tidak ada. Di
America/New_York, 2026-03-08 02:30 terlewati karena jam melompat dari 02:00 ke 03:00. - Tumpang tindih (overlap): saat jam dimundurkan, sebagian waktu lokal terjadi dua kali. 2026-11-01 01:30 terjadi sekali dalam EDT (UTC−04:00) dan sekali lagi satu jam kemudian dalam EST (UTC−05:00).
Pustaka menangani kasus-kasus ini secara berbeda. Konverter LeedyBox menggunakan waktu valid yang lebih akhir dalam celah (03:30 dalam contoh ini) dan kemunculan yang lebih awal dalam tumpang tindih, serta menjelaskannya dalam sebuah catatan. Tugas terjadwal menghadapi masalah yang sama; lihat Cara Membaca Ekspresi Cron.
ISO 8601, RFC 3339, dan Tanggal HTTP
Jika suatu momen harus mudah dibaca, tuliskan dalam ISO 8601 atau profil internetnya yang lebih ketat, RFC 3339:
2023-11-14T22:13:20Z
2023-11-15T07:13:20+09:00
2023-11-14T22:13:20.500Z
Z berarti UTC. Dengan Z atau offset, string tersebut tidak ambigu. String tanpa keduanya, seperti 2023-11-14T22:13:20, adalah waktu lokal dalam zona yang tidak diketahui, dan parser berbeda-beda dalam cara membacanya.
Header HTTP seperti Last-Modified dan Expires menggunakan format yang lebih lama, turunan dari format tanggal email (RFC 2822, kini RFC 5322), yang ditulis dalam GMT: Tue, 14 Nov 2023 22:13:20 GMT.
Masalah Tahun 2038
Banyak sistem lama menyimpan waktu Unix dalam bilangan bulat 32-bit bertanda (signed). Nilai terbesarnya, 2147483647, adalah 2038-01-19 03:14:07 UTC. Satu detik kemudian penghitung meluap (overflow) menjadi -2147483648, yang terbaca sebagai 1901-12-13 20:45:52 UTC. Sistem operasi dan bahasa pemrograman saat ini sebagian besar menggunakan nilai waktu 64-bit, yang mencakup ratusan miliar tahun, tetapi kolom 32-bit masih muncul di perangkat tertanam (embedded), format file, kolom database, dan protokol jaringan. Jika kode atau data Anda menyimpan detik dalam 32 bit, rencanakan perubahannya sejak dini dan uji tanggal setelah 2038 sekarang juga.
Timestamp dalam Kode dan Database
JavaScript bekerja dalam milidetik:
Math.floor(Date.now() / 1000); // waktu Unix saat ini dalam detik
new Date(1700000000 * 1000).toISOString(); // "2023-11-14T22:13:20.000Z"
Date.parse("2026-10-03T09:00:00+09:00") / 1000; // 1790985600
time.time() di Python mengembalikan detik sebagai float. Berikan tz=timezone.utc, karena jika tidak, fromtimestamp() mengembalikan waktu lokal komputer tanpa zona:
import time
from datetime import datetime, timezone
int(time.time()) # detik
datetime.fromtimestamp(1700000000, tz=timezone.utc) # 2023-11-14 22:13:20+00:00
datetime.fromisoformat("2026-10-03T09:00:00+09:00").timestamp() # 1790985600.0
Di SQL, fungsinya berbeda-beda menurut database:
-- PostgreSQL
SELECT extract(epoch FROM now()); -- detik, dengan pecahan
SELECT to_timestamp(1700000000); -- timestamp with time zone
-- MySQL
SELECT UNIX_TIMESTAMP();
SELECT FROM_UNIXTIME(1700000000); -- dalam zona waktu sesi
Untuk penyimpanan, beberapa kebiasaan berikut mencegah sebagian besar masalah:
- Simpan momen yang sudah terjadi dalam UTC, baik di kolom timestamp-with-time-zone maupun sebagai bilangan bulat 64-bit yang satuannya menjadi bagian dari nama kolom, seperti
created_at_ms. - Simpan acara lokal di masa depan, seperti rapat pukul 09:00 di Seoul, sebagai tanggal dan waktu lokal ditambah nama zona IANA, lalu hitung timestamp-nya saat diperlukan, agar perubahan aturan di kemudian hari tidak menggeser jadwal rapat.
- Jangan mencampur satuan dalam satu kolom; satuan yang salah membuat nilai meleset dengan faktor 1.000 atau lebih.
Pertanyaan Umum
Mengapa timestamp saya dikonversi menjadi tanggal di tahun 1970?
Nilainya mungkin dibaca dalam satuan yang salah: detik yang dibaca sebagai milidetik jatuh pada Januari 1970, dan milidetik yang dibaca sebagai detik jatuh puluhan ribu tahun di masa depan. Hitung digitnya atau pilih satuannya di konverter.
Apakah timestamp Unix bergantung pada zona waktu saya?
Tidak. Timestamp Unix menghitung detik dari satu momen tetap dalam UTC. Hanya tanggal dan waktu yang ditampilkan untuknya yang bergantung pada zona waktu.
Bisakah waktu Unix merepresentasikan detik kabisat?
Tidak. Waktu Unix menganggap setiap hari berisi 86.400 detik, sehingga waktu UTC seperti 23:59:60 tidak memiliki timestamp sendiri.