Stempel waktu Unix adalah salah satu format data terpenting dalam pemrograman — stempel waktu tersebut muncul dalam catatan basis data, respons API, file log, metadata sistem file, token autentikasi, dan banyak tempat lainnya. Formatnya sangat sederhana: bilangan bulat tunggal yang mewakili detik (atau milidetik, mikrodetik, atau nanodetik) sejak 1 Januari 1970. Namun bekerja dengan stempel waktu dengan benar ternyata sangat rumit karena penanganan zona waktu, ketidaksesuaian presisi antar sistem, dan kasus tepi DST. Bagian di bawah ini menjelaskan apa itu waktu Unix dan mengapa waktu itu ada, cara menangani zona waktu dengan benar saat melakukan konversi, dan bug umum yang menyerang pengembang bahkan setelah pengalaman bertahun-tahun.
Apa Itu Waktu Unix dan Mengapa Itu Ada
Waktu Unix, juga disebut waktu Epoch atau waktu POSIX, adalah jumlah detik yang berlalu sejak 1 Januari 1970 00:00:00 UTC — titik referensi yang disebut zaman Unix. Nilai negatif mewakili tanggal sebelum periode tersebut, nilai positif mewakili tanggal setelahnya. Format ini berasal dari awal tahun 1970-an ketika sistem Unix memerlukan cara yang ringkas dan tidak bergantung pada zona waktu untuk menyimpan stempel waktu dalam metadata sistem file dan catatan log. Sebuah bilangan bulat bertanda 32-bit tunggal dapat mewakili tanggal dari 1901 hingga 2038, yang tampaknya cukup pada waktu desain tetapi menciptakan Masalah Tahun 2038 yang terkenal ketika rentang tersebut berakhir. Sistem modern menggunakan bilangan bulat 64-bit, sehingga masa kadaluwarsanya mencapai tahun 292 miliar. Keanggunan waktu Unix adalah ia tidak memiliki zona waktu, tidak ada DST, tidak ada detik kabisat (secara resmi — sebagian besar implementasi hanya mengaburkan detik kabisat yang jarang terjadi), dan tidak ada kompleksitas kalender. Ini adalah penghitung yang meningkat secara monoton yang secara jelas mengidentifikasi momen tertentu. Zona waktu, tanggal kalender, dan format yang dapat dibaca manusia semuanya ditempatkan di bagian atas pada waktu tampilan. Hal ini menjadikan waktu Unix sebagai format pilihan untuk perbandingan (`if (tokenExpiresAt < sekarang)`), menyortir, dan menyimpan stempel waktu dalam database di seluruh sistem terdistribusi yang mencakup zona waktu. Format yang dapat dibaca manusia seperti `21-04-2024 11:58:41` berasal dari nilai Unix yang disimpan hanya saat ditampilkan kepada pengguna.
Penanganan Zona Waktu — Bagian Halusnya
Stempel waktu Unix sendiri tidak memiliki zona waktu — stempel waktu ini mewakili momen tertentu dalam waktu absolut. Saat Anda mengonversi ke bentuk yang dapat dibaca manusia, Anda memilih zona waktu untuk ditampilkan, dan stempel waktu yang sama menghasilkan waktu lokal berbeda di zona berbeda. Misalnya, 1713711521 detik setelah epoch adalah 15:58:41 UTC, tetapi momen yang sama adalah 11:58:41 EDT (Amerika/New_York, UTC-4), 08:58:41 PDT (Amerika/Los_Angeles, UTC-7), 00:58:41 JST hari berikutnya (Asia/Tokyo, UTC+9), dan banyak lainnya waktu lokal di seluruh dunia. Praktiknya memerlukan nama zona waktu IANA seperti `Amerika/New_York`, bukan offset tetap seperti `UTC-05:00`, karena nama IANA menyandikan riwayat DST lengkap. Mengatakan "16.00 EST pada 15 Juli 2024" sebenarnya ambigu karena Waktu Bagian Timur menetapkan DST dan tanggal Juli menggunakan EDT (UTC-4), bukan EST (UTC-5). Zona waktu IANA menyelesaikan ambiguitas ini secara otomatis — API Intl browser dan pustaka sisi server seperti pytz, zona waktu momen, dan ZoneId Java semuanya menggunakan database IANA dan menangani transisi DST historis dengan benar. Konverter ini menggunakan Intl.DateTimeFormat bawaan browser dengan dukungan zona waktu IANA penuh, yang berarti konverter ini menghasilkan waktu lokal yang benar untuk zona valid apa pun termasuk tanggal historis sejak tahun 1970 atau lebih awal.
Bug Umum yang Ditangkap Bahkan Pengembang Berpengalaman
Beberapa bug stempel waktu sering muncul sehingga layak untuk diinternalisasikan sebagai daftar periksa. Pertama, kebingungan detik vs milidetik: Objek Tanggal JavaScript bekerja dalam milidetik sedangkan time.time() Python bekerja dalam hitungan detik, dan secara tidak sengaja mencampurkannya akan mengalikan atau membagi tanggal Anda dengan 1000. Periksa besarnya: angka 10 digit adalah detik, 13 digit adalah milidetik, 16 digit adalah mikrodetik. Kedua, asumsi zona waktu dalam penguraian: string "21-04-2024 11:58:41" tidak memiliki zona waktu, dan parser yang berbeda menetapkan asumsi yang berbeda secara default. Konstruktor Tanggal JavaScript memperlakukannya sebagai waktu lokal; Datetime.fromisoformat Python memperlakukannya sebagai naif (tidak ada zona waktu). Selalu lampirkan zona waktu eksplisit ke string yang ambigu sebelum menguraikan. Ketiga, kasus tepi DST pada transisi musim semi dan musim gugur: pukul 02.30 pada hari maju musim semi tidak ada di sebagian besar zona waktu AS (jam melonjak dari 01.59 ke 03.00), dan 01.30 pada hari mundur terjadi dua kali. Aritmatika tanggal yang menambah atau mengurangi jam melintasi batas DST dapat memberikan hasil yang mengejutkan kecuali Anda menggunakan perpustakaan yang mendukung IANA. Keempat, "sekarang" melayang di seluruh server: jam server melayang dalam milidetik atau detik, sehingga token yang dihasilkan di satu server dan divalidasi di server lain memerlukan jendela toleransi. Kelima, detik kabisat: jarang relevan dalam praktik karena sebagian besar sistem mengabaikannya, namun penting untuk penerapan ilmiah atau keuangan yang tepat. Pengonversi ini menghindari sebagian besar hal tersebut dengan menggunakan API Intl browser yang telah teruji dengan baik, namun konsep dasarnya tetap penting saat menulis kode yang menggunakan nilai yang dikonversi.