Konverter Timestamp Unix ke Tanggal
Apa pun yang Anda masukkan di sini tidak disimpan, dicatat, atau dibagikan.
Ubah timestamp Unix menjadi tanggal yang mudah dibaca atau sebaliknya. Satuannya dideteksi otomatis dan setiap hasil menampilkan zona waktunya.
Cara memakai
- Tempel timestamp, atau tanggal seperti 2025-01-01T00:00:00.
- Pilih zona waktu bila Anda butuh selain zona Anda sendiri.
- Salin format mana pun yang Anda perlukan.
Detik, milidetik, dan satuan yang lebih kecil
Waktu Unix didefinisikan dalam detik. Date di JavaScript memakai milidetik. Hampir semua bug tanggal di basis kode campuran berawal dari batas ini.
Gejalanya mudah dikenali setelah Anda tahu. Nilai detik yang diberikan ke sesuatu yang mengharapkan milidetik akan jatuh di dini hari 1 Januari 1970 - jika tanggal di antarmuka Anda tampil sebagai 1970, hampir selalu inilah penyebabnya. Nilai milidetik yang dibaca sebagai detik jatuh di sekitar tahun 55.000, yang biasanya ketahuan, tetapi tidak selalu, karena ada kode tampilan yang menampilkannya tanpa protes.
Satuan di sini ditebak dari jumlah digit, sebuah heuristik tetapi dapat diprediksi dan dijelaskan: timestamp masa kini memiliki 10 digit dalam detik, 13 dalam milidetik, 16 dalam mikrodetik, dan 19 dalam nanodetik, dan rentangnya tidak tumpang tindih untuk tanggal mana pun yang realistis dipakai. Satuan yang dipilih ditampilkan, bukan diasumsikan diam-diam, dan bisa Anda ubah. Timestamp mikrodetik muncul di Postgres dan trace Chrome; nanodetik di Go, Prometheus, dan InfluxDB. Nilai nanodetik melebihi batas angka JavaScript yang bisa disimpan secara tepat, jadi konversinya dilakukan dengan BigInt.
Yang tidak ada di dalam timestamp
Timestamp Unix adalah sebuah momen, dan tidak lebih. Tidak ada zona waktu, offset, atau kalender di dalamnya. Dua orang yang membaca timestamp yang sama di Tokyo dan Lisbon sedang melihat momen yang sama dan akan dengan benar mencatat jam lokal yang berbeda. Ini justru kelebihan: sebuah momen tidak ambigu, sesuatu yang tidak pernah bisa dicapai jam lokal.
Akibatnya, timestamp tidak bisa memberi tahu hari apa saat itu secara lokal, dan mengubahnya menjadi tanggal memerlukan pemilihan zona. Karena itulah setiap output di sini menyertakan zonanya, dengan UTC selalu ditampilkan berdampingan dengan waktu lokal Anda agar keduanya bisa langsung dibandingkan.
Ini juga berarti timestamp adalah cara yang salah untuk menyimpan hal yang pada dasarnya bersifat lokal. Rapat rutin pukul 09.00, ulang tahun, jam buka toko: semuanya jam lokal yang terikat pada zona dan aturannya, dan menyimpannya sebagai momen akan merusaknya saat offset zona itu berubah lagi. Simpan jam lokal dan nama zonanya, lalu hitung momennya saat diperlukan.
Detik kabisat
Waktu Unix didefinisikan seolah-olah setiap hari tepat 86.400 detik. Bumi tidak mau diatur, jadi detik kabisat disisipkan ke UTC agar tetap selaras dengan rotasi planet - dua puluh tujuh kali sejak 1972.
Karena definisinya tidak menyediakan tempat untuk itu, waktu Unix menangani detik kabisat dengan mengulang satu nilai, bukan menambah satu. Tidak ada timestamp Unix yang mewakili detik kabisat itu sendiri, sehingga selisih antara waktu Unix dan TAI terus bertambah selama puluhan tahun alih-alih tetap. Kode yang menghitung durasi dengan mengurangkan dua timestamp Unix diam-diam meleset sebanyak jumlah detik kabisat di antaranya, yang hampir tidak pernah penting tetapi sesekali sangat penting.
Penyedia besar menghindari diskontinuitas ini dengan smearing: Google dan AWS menyebarkan detik tambahan itu ke rentang waktu sebelum dan sesudah peristiwanya sehingga jam tidak pernah mengulang nilai, dengan konsekuensi jam berjalan sedikit lebih lambat selama sehari. Perhatikan bahwa jam yang di-smear berbeda nilainya dengan jam yang tidak selama rentang itu, hal yang perlu diketahui jika Anda membandingkan timestamp antarpenyedia.
2038 dan batas-batas lainnya
Integer bertanda 32-bit habis pada 19 Januari 2038 pukul 03:14:07 UTC, dan detik berikutnya kembali ke Desember 1901. Apa pun yang masih menyimpan waktu Unix di field 32-bit - sistem embedded, format file lama, kolom database yang tidak pernah diperlebar - akan gagal saat itu. Karena itulah timestamp setelah titik tersebut diberi tanda di sini. Penyimpanan 64-bit mendorong batasnya jauh melampaui umur alam semesta dan itulah yang dipakai sistem saat ini.
Penyimpanan 32-bit tanpa tanda menggeser batasnya ke 2106, dengan konsekuensi tidak bisa menyatakan apa pun sebelum 1970. Timestamp negatif berfungsi di sini: -86400 adalah 31 Desember 1969, dan tanggal hingga awal kalender Gregorian bisa dikonversi dengan baik. Date di JavaScript punya batasnya sendiri, 8,64e15 milidetik di kedua sisi epoch, sekitar 273.000 tahun, dan nilai di luarnya dilaporkan sebagai di luar rentang, bukan ditampilkan sebagai Invalid Date.
Format teks, dan mana yang sebaiknya dikeluarkan
ISO 8601 adalah standar internasional untuk menuliskan tanggal dan waktu, sedangkan RFC 3339 adalah profil yang lebih ketat dari standar itu dan dipakai oleh protokol internet. Bentuk RFC 3339 - 2026-03-14T09:30:00Z, atau dengan offset seperti +09:00 - adalah bentuk yang sebaiknya dikeluarkan oleh sebuah API, karena urutannya tetap benar saat diurutkan sebagai teks, maknanya tidak mendua, dan bisa diurai di mana saja.
Huruf Z berarti UTC, dan offset seperti +09:00 berarti selisih tetap terhadap UTC. Keduanya bukan zona waktu. Asia/Tokyo barulah zona waktu: seperangkat aturan yang menyatakan berapa offset-nya pada tanggal tertentu, lengkap dengan riwayat perubahannya. Offset memberi tahu Anda apa yang ditunjukkan jam saat itu; hanya nama zona yang memberi tahu kapan jam akan menunjukkan hal itu di masa depan.
Format yang sebaiknya dihindari di dalam data: apa pun yang memakai tahun dua digit, apa pun yang memakai garis miring, dan tanggal RFC 2822 dari header email, yang masih membawa singkatan zona yang sudah usang. Singkatan adalah yang paling parah: CST bisa berarti Central Standard Time di Amerika Utara, China Standard Time, maupun Cuba Standard Time, sedangkan IST dipakai untuk India, Irlandia, dan Israel sekaligus.
Menyimpan waktu di basis data
Tipe timestamptz milik PostgreSQL adalah tipe yang sebenarnya dibutuhkan sebagian besar aplikasi. Meski namanya begitu, tipe ini tidak menyimpan zona: ia mengubah masukan menjadi UTC saat ditulis dan menampilkannya dalam zona sesi saat dibaca, dan itulah perilaku yang Anda inginkan untuk sebuah titik waktu. Sebaliknya, timestamp biasa menyimpan teks jam dinding apa adanya tanpa zona sama sekali, sehingga membandingkan dua nilai semacam itu yang berasal dari sumber berbeda akan menghasilkan omong kosong yang tak bersuara.
DATETIME di MySQL berperilaku seperti tipe polos tadi, sedangkan TIMESTAMP mengubah nilainya ke UTC tetapi terbatas pada rentang 32 bit yang berakhir pada 2038, sebuah batasan nyata bagi apa pun yang menyimpan tanggal di masa depan. SQLite sama sekali tidak punya tipe tanggal dan menyimpan konvensi mana pun yang Anda pilih, biasanya teks ISO 8601 atau bilangan bulat.
Disiplin yang tetap bertahan menghadapi semua itu adalah menyimpan titik waktu dalam UTC, melakukan konversi di tepi sistem, dan menyimpan zona pengguna sebagai kolom terpisah bila Anda perlu menampilkan atau menjadwalkan sesuatu untuknya. Jika sebuah nilai memang benar-benar waktu jam dinding setempat - jam buka toko, rapat rutin pukul 09:00 - simpanlah waktu lokal beserta nama zonanya, lalu hitung titik waktunya ketika dibutuhkan, karena offset bisa berubah karena peraturan.
Jam saling berbeda, dan sebagian berjalan mundur
Jam dinding sebuah mesin disetel oleh NTP, artinya jam itu bisa melompat maju atau mundur. Karena itu, mengukur durasi dengan mengurangkan dua pembacaan jam dinding sesekali menghasilkan waktu yang negatif, dan cukup sering menghasilkan angka yang salah. Jam monotonik ada untuk keperluan ini: jam itu hanya bergerak maju, dan itulah yang dipakai performance.now, clock_gettime dengan CLOCK_MONOTONIC, serta setiap pustaka benchmark.
Antarmesin masalahnya lebih buruk, karena dua server tidak pernah benar-benar selaras. Mengurutkan peristiwa di sistem terdistribusi berdasarkan stempel waktunya menghasilkan urutan yang bertentangan dengan sebab-akibat - sebuah balasan tercatat lebih dulu daripada pesan yang dibalasnya - dan itulah alasan jam logis serta nomor urut diciptakan.
Untuk aplikasi biasa, sarannya jauh lebih sederhana: jangan memakai stempel waktu sebagai pengenal unik, jangan menganggap dua peristiwa dengan stempel waktu sama terjadi bersamaan, dan perkirakan ada selisih jam setidaknya beberapa detik saat membandingkan apa pun yang dicatat di mesin berbeda. Validasi token memberi toleransi selisih justru karena alasan ini.
Menampilkan waktu kepada manusia
Titik waktu yang tersimpan harus ditampilkan dalam zona pembacanya, dalam format lokalnya, dan dalam bahasanya. Di JavaScript, API Intl.DateTimeFormat mengerjakan ketiganya berdasarkan pengaturan peramban, dan ia menangani detail yang sering salah bila dikerjakan manual: nama bulan dalam bahasa yang tepat, urutan tanggal dan bulan yang tepat, serta pemilihan format dua belas atau dua puluh empat jam berdasarkan kelaziman setempat, bukan selera pembuatnya.
Waktu relatif - tiga jam lalu, dua hari lagi - terasa lebih akrab untuk peristiwa yang baru terjadi, tetapi justru lebih buruk untuk yang sudah lama, sebab tidak ada orang yang bisa berbuat apa-apa dengan 431 hari lalu. Pola yang umum adalah memakai waktu relatif dalam satu atau dua hari pertama, lalu beralih ke tanggal absolut, dengan stempel waktu lengkap yang muncul saat kursor diarahkan atau saat ditekan lama.
Ada dua detail yang bedanya benar-benar terlihat. Tampilkan tanggal dalam zona pengguna, bukan zona server, yang berarti mengirimkan sebuah titik waktu lalu memformatnya di sisi klien alih-alih merangkai teks di sisi server. Dan berilah label zona pada apa pun yang bisa ditafsirkan ganda, karena jam rapat tanpa zona adalah cara paling ampuh untuk membuat seseorang datang terlambat satu jam.
Tanggal yang tidak pernah ada, dan kasus tepi lainnya
Menjadwalkan apa pun pada pukul 02:30 di zona yang menerapkan daylight saving berarti memesan satu insiden setiap tahun: waktu itu tidak ada pada peralihan musim semi dan muncul dua kali pada peralihan musim gugur. Pekerjaan yang harus berjalan tepat sekali sebaiknya dijalankan dalam UTC, atau di luar rentang pukul satu sampai tiga tempat peralihan itu terjadi.
Aritmetika kalender punya jebakannya sendiri. Menambahkan satu bulan pada 31 Januari tidak punya satu jawaban yang benar, dan pustaka yang berbeda terbelah antara 28 Februari dan 3 Maret. Menambahkan 24 jam tidak sama dengan menambahkan satu hari bila melintasi peralihan. Tahun kabisat menuntut aturan yang utuh - habis dibagi empat, kecuali tahun abad, kecuali yang habis dibagi 400 - dan 29 Februari merusak logika hari jadi setiap empat tahun sekali.
Batasnya pun nyata. Waktu 32 bit bertanda berakhir pada 19 Januari 2038, dan itu masih penting bagi perangkat tertanam serta kolom basis data lama; Date di JavaScript mencakup kira-kira 273.000 tahun di kedua sisi 1970 dan melaporkan apa pun di luar itu sebagai tidak valid. Keduanya layak diuji bila data Anda memuat tanggal yang jauh di masa depan, seperti yang lazim pada sistem kredit rumah, dana pensiun, dan kearsipan.
Pertanyaan umum
- Timestamp saya dalam detik atau milidetik?
- Hitung digitnya. Timestamp masa kini dalam detik punya 10 digit, milidetik 13, mikrodetik 16, dan nanodetik 19. Alat ini mendeteksi satuannya dan memberi tahu mana yang dipakai, karena tertukar di antara keduanya adalah bug tanggal paling umum yang ada: detik yang dibaca sebagai milidetik jatuh di Januari 1970, dan milidetik yang dibaca sebagai detik jatuh puluhan ribu tahun di masa depan.
- Kenapa timestamp yang sama menampilkan jam berbeda?
- Timestamp Unix adalah titik waktu mutlak tanpa zona waktu yang melekat. Jam dinding yang sesuai dengannya sepenuhnya bergantung pada tempat Anda berada, dan itulah sebabnya setiap keluaran di sini mencantumkan zonanya dan UTC selalu ditampilkan di sampingnya.
- Apa yang terjadi pada 2038?
- Sistem yang menyimpan waktu Unix dalam bilangan bulat 32 bit bertanda akan meluap pada 2038-01-19T03:14:07Z dan berputar kembali ke 1901. Alat ini menandai setiap timestamp yang melewati titik itu. Penyimpanan 64 bit modern tidak terpengaruh.
- Apakah waktu Unix menghitung detik kabisat?
- Tidak. Waktu Unix didefinisikan seolah setiap hari tepat 86.400 detik, jadi detik kabisat dilewati alih-alih dihitung. Karena itulah ia tidak bisa mewakili detik kabisat itu sendiri, dan karena itu pula konversi antara waktu Unix dan TAI bukan sekadar penggeseran sederhana.
- Bisakah ia menangani tanggal sebelum 1970?
- Bisa. Timestamp sebelum epoch bernilai negatif, jadi -86400 adalah 31 Desember 1969.
Terakhir diperbarui:
Sertakan langkah, hasil yang diharapkan, dan hasil sebenarnya. Hapus rahasia dan data pribadi.
