Menu

Date dan Waktu JavaScript: new Date, Format, dan Perbandingan

Cara kerja objek Date JavaScript yang sebenarnya: membuat tanggal, memformatnya, melakukan aritmetika, menangani zona waktu, dan keanehan yang sering menjebak.

Halaman ini dilengkapi editor yang bisa dijalankan. Edit, jalankan, dan lihat output-nya seketika.

Objek Date Adalah Satu Titik Waktu

Date di JavaScript mewakili satu momen tunggal. Di dalamnya, ia hanyalah jumlah milidetik sejak 1 Januari 1970 UTC ("Unix epoch"). Semua yang lain, seperti tahun, bulan, hari, zona waktu, dan format, adalah tampilan yang dibangun di atas angka itu.

now.getTime() adalah jumlah milidetik mentahnya. Semua yang dilakukan Date, seperti membandingkan, menambah hari, atau memformat, pada dasarnya mengolah angka itu lalu menafsirkannya ulang.

Simpan model ini di kepalamu. Date bukanlah "14 Maret di Paris". Ia adalah momen universal yang bisa ditampilkan sebagai 14 Maret di Paris, atau 13 Maret di Los Angeles, tergantung zona waktu yang kamu pakai untuk melihatnya.

Membuat Tanggal

Ada empat cara utama untuk membuat Date:

Dua hal yang perlu diperhatikan:

  • Constructor berbasis bagian-bagian tanggal memakai bulan yang dimulai dari nol. 2 berarti Maret. Januari adalah 0. Ini sumber bug selisih satu yang tidak ada habisnya. Di bagian lain API-nya, bulan juga dimulai dari 0, jadi setidaknya konsisten.
  • new Date("2026-03-14") (tanpa jam) di-parse sebagai tengah malam UTC. new Date("2026-03-14T09:30") (tanpa Z) di-parse sebagai waktu lokal. Ketidaksimetrisan ini adalah jebakan klasik.

Untuk "saat ini" dalam bentuk angka, utamakan Date.now() karena tidak perlu membuat objek:

Date.now() adalah alat yang tepat untuk mengukur waktu yang berlalu, timeout, dan apa pun yang tidak butuh aritmetika kalender.

Membaca Bagian-Bagian Tanggal

Begitu punya Date, kamu mengambil komponennya dengan getter. Setiap getter punya dua versi: waktu lokal dan UTC.

Getter lokal bergantung pada mesin siapa pun yang menjalankan kodenya. Kalau kamu menyimpan atau membandingkan tanggal antar pengguna dan server, pilih UTC secara eksplisit, atau kamu akan mengejar bug hantu. Pegangan praktisnya: pakai getter UTC untuk apa pun yang masuk ke database atau log; pakai getter lokal untuk apa pun yang akan kamu tampilkan ke manusia.

Jangan pakai getYear(). Itu method lawas yang mengembalikan year - 1900 dan hanya ada demi kompatibilitas. Selalu pakai getFullYear().

Memformat untuk Manusia

Hindari date.toString() untuk apa pun yang penting, karena output-nya bergantung pada locale dan engine. Ada dua formatter yang perlu kamu kenal.

Untuk string standar yang dibaca mesin, pakai toISOString():

Itulah format yang dipakai saat mencatat log, menyimpan di JSON, atau mengirim lewat jaringan. Selalu UTC, selalu tidak ambigu.

Untuk string yang dilihat manusia, pakai Intl.DateTimeFormat atau method toLocale* yang membungkusnya:

Intl.DateTimeFormat menangani locale, zona waktu, dan setiap kombinasi field yang kamu inginkan. Pakai itu sebelum menulis format manual seperti ${year}-${month}-${day}, karena penyusunan string seperti itulah tempat bug selisih satu bulan bersarang.

Membandingkan Tanggal

Dua objek Date yang mewakili momen yang sama tidak bernilai sama dengan ===, karena === mengecek identitas objek, bukan nilainya. Bandingkan timestamp-nya:

Untuk urutan, operator perbandingan langsung berfungsi karena mengubah tanggal menjadi angka:

Pengurangan memberimu selisihnya dalam milidetik. Bagi dengan 1000 * 60 * 60 * 24 untuk mendapatkan hari. Tulis konstanta itu lengkap pada awalnya; lama-lama kamu akan langsung mengenali 86_400_000 begitu melihatnya.

Aritmetika Tanggal

Tidak ada method addDays. Cara yang lazim adalah memakai setDate, setMonth, dan sejenisnya: method itu menerima nilai di luar rentang dan otomatis bergulir dengan benar:

Dua hal yang layak disorot:

  • new Date(date) menyalin tanggalnya. setDate mengubah objek, jadi selalu salin dulu atau kamu akan mengubah nilai milik pemanggil.
  • setDate(35) pada bulan yang punya 31 hari otomatis bergulir ke bulan berikutnya. Sama halnya dengan setMonth(14), yang memajukan tahunnya. Ini membuat aritmetika jauh lebih mudah daripada kelihatannya.

Untuk hal yang rumit, seperti hari kerja, acara berulang, atau durasi yang memperhitungkan bulan, pakai library (date-fns, Luxon, atau API Temporal yang akan datang). Menulis sendiri perhitungan kalender yang lebih dari "tambah beberapa hari" adalah jebakan tanpa ujung.

Kenyataan Soal Zona Waktu

Zona waktu adalah sumber bug tanggal yang terbesar. Aturan yang layak kamu pahami betul:

  • Date menyimpan momen UTC. Zona waktu baru diterapkan saat kamu membaca bagian-bagiannya atau memformatnya.
  • Zona waktu yang dipakai getHours(), getDate(), dan sejenisnya adalah zona waktu lokal mesin yang menjalankan kodenya. Server dan browser sering berbeda pendapat.
  • new Date("2026-03-14") (hanya tanggal) di-parse sebagai UTC. new Date("2026-03-14T00:00") (dengan jam, tanpa zona) di-parse sebagai waktu lokal. new Date(2026, 2, 14) (berbasis bagian) memakai waktu lokal.

Saat kamu butuh zona waktu tertentu untuk ditampilkan, berikan timeZone ke Intl.DateTimeFormat:

Momen yang sama, dua tampilan. Objek Date-nya sendiri tidak berubah.

Contoh Kecil yang Berfungsi

Menggabungkan semuanya: sebuah fungsi yang memformat berapa lama yang lalu sesuatu terjadi:

Timestamp masuk, string yang mudah dibaca manusia keluar. Inilah bentuk 90% kode tanggal di dunia nyata: kurangi dua momen, bagi dengan satuan, bulatkan, lalu format.

Yang Perlu Kamu Ingat

  • Date adalah momen UTC. Zona waktu muncul saat kamu membaca atau memformatnya.
  • Pakai Date.now() untuk timestamp, new Date() untuk urusan kalender.
  • Pakai toISOString() untuk penyimpanan dan log, Intl.DateTimeFormat untuk pengguna.
  • Bandingkan dengan getTime() atau </>. Jangan pernah ===.
  • Bulan dimulai dari 0. Waspadai jebakan parsing string yang hanya berisi tanggal.
  • Untuk perhitungan tanggal yang serius, pakai library.

Berikutnya: URL dan Query String

Tanggal sering muncul di URL, misalnya untuk memfilter berdasarkan rentang tanggal atau mengirim timestamp sebagai parameter query. Mem-parsing dan menyusun URL secara manual sama rawannya dengan memformat tanggal secara manual, dan library standar punya objek URL yang menanganinya dengan rapi. Itu topik berikutnya.

Pertanyaan yang sering diajukan

Bagaimana cara mendapatkan tanggal saat ini di JavaScript?

Panggil new Date() tanpa argumen. Hasilnya objek Date yang mewakili saat constructor itu berjalan. Kalau kamu hanya butuh timestamp berupa angka (milidetik sejak 1970), pakai Date.now(): lebih cepat dan tidak membuat objek utuh.

Bagaimana cara membandingkan dua tanggal di JavaScript?

Bandingkan timestamp-nya, bukan objek Date-nya. a.getTime() < b.getTime() berfungsi, begitu juga a < b karena < mengubah tanggal menjadi angka. Tetapi a === b tidak berfungsi: === mengecek identitas objek, jadi dua objek Date yang mewakili momen yang sama tidak pernah sama secara ketat.

Bagaimana cara memformat tanggal di JavaScript?

Untuk apa pun yang dilihat pengguna, pakai Intl.DateTimeFormat atau date.toLocaleDateString(), karena keduanya menangani locale dan zona waktu dengan benar. Untuk output yang dibaca mesin, date.toISOString() memberimu string standar seperti 2026-03-14T09:30:00.000Z. Hindari date.toString() untuk penyimpanan; formatnya bergantung pada locale.

Mengapa tanggal JavaScript-ku meleset satu hari?

Biasanya masalah zona waktu. new Date('2026-03-14') di-parse sebagai tengah malam UTC, tetapi date.getDate() mengembalikan hari dalam zona waktu lokal, yang bisa jadi hari sebelumnya. Pakai getUTCDate() untuk hari dalam UTC, atau buat tanggal dengan new Date(year, month, day) yang memakai waktu lokal sejak awal.

Ilustrasi bahasa pemrograman di Coddy

Belajar coding dengan Coddy

Mulai