1. Aturan Emas Menangani Tanggal dan Waktu (Date) di Aplikasi Web
Objek bawaan Date di JavaScript sebenarnya menyimpan satu angka sederhana di balik layar: **jumlah milidetik yang telah berlalu sejak 1 Januari 1970 00:00:00 UTC (Unix Epoch)**.
Namun, new Date() memiliki beberapa jebakan warisan tahun 1995 yang wajib Anda waspadai:
- Indeks Bulan Dimulai dari
0(0= Januari,11= Desember), sedangkan Tanggal Hari Dimulai dari1! Menulisnew Date(2026, 10, 16)bukanlah 16 Oktober 2026, melainkan 16 November 2026! - Perbedaan Penguraian String Tanggal:
- Selalu gunakan format standar ISO 8601 lengkap dengan zona waktu saat bertukar data antara klien dan server:
"2026-10-16T07:30:00.000Z"(akhiranZberarti UTC) atau"2026-10-16T14:30:00+07:00"(WIB). - Gunakan
new Date().toISOString()untuk menghasilkan string waktu UTC standar yang siap dikirim ke API/database.
- Selalu gunakan format standar ISO 8601 lengkap dengan zona waktu saat bertukar data antara klien dan server:
const sekarang = new Date("2026-10-16T07:30:00.000Z");
// Mendapatkan timestamp milidetik saat ini secara cepat:
const capWaktuMs = Date.now();
console.log(sekarang.toISOString()); // "2026-10-16T07:30:00.000Z"
2. Kekuatan API Internasionalisasi Bawaan (Intl) — Tanpa Pustaka Berat!
Di masa lalu, pengembang sering memasang pustaka tanggal dan pemformatan berukuran ratusan kilobyte hanya untuk menampilkan "Jumat, 16 Oktober 2026", "Rp 1.250.000", atau "2 jam yang lalu".
Kini, mesin JavaScript di semua peramban dan Node.js sudah memiliki namespace bawaan Intl (ECMA-402) yang sangat cepat, akurat untuk Bahasa Indonesia ("id-ID"), dan berukuran 0 KB!
A. Memformat Tanggal dan Zona Waktu (Intl.DateTimeFormat)
Anda bahkan dapat menentukan timeZone: "Asia/Jakarta" (WIB), "Asia/Makassar" (WITA), atau "Asia/Jayapura" (WIT) secara eksplisit agar tampilan waktu selalu konsisten:
const waktuServer = new Date("2026-10-16T07:30:00Z");
const pemformatTanggalWib = new Intl.DateTimeFormat("id-ID", {
dateStyle: "full",
timeStyle: "short",
timeZone: "Asia/Jakarta"
});
console.log(pemformatTanggalWib.format(waktuServer));
// Keluaran: "Jumat, 16 Oktober 2026 pukul 14.30"
B. Memformat Mata Uang Rupiah, Persentase, dan Angka Ringkas (Intl.NumberFormat)
// 1. Format Mata Uang Rupiah
const formatRupiah = new Intl.NumberFormat("id-ID", {
style: "currency",
currency: "IDR",
maximumFractionDigits: 0
});
console.log(formatRupiah.format(1250000)); // "Rp 1.250.000"
// 2. Format Angka Ringkas (mis. untuk jumlah tayangan "1,2 rb" atau "3,5 jt")
const formatRingkas = new Intl.NumberFormat("id-ID", {
notation: "compact",
compactDisplay: "short"
});
console.log(formatRingkas.format(14500)); // "15 rb" (bawaannya dibulatkan ke dua digit signifikan; tambahkan maximumFractionDigits: 1 untuk "14,5 rb")
C. Waktu Relatif (Intl.RelativeTimeFormat) dan Daftar Kalimat (Intl.ListFormat)
// 1. Menampilkan "3 hari yang lalu" atau "dalam 2 bulan"
const formatRelatif = new Intl.RelativeTimeFormat("id-ID", { numeric: "auto" });
console.log(formatRelatif.format(-1, "day")); // "kemarin"
console.log(formatRelatif.format(-3, "day")); // "3 hari yang lalu"
console.log(formatRelatif.format(2, "hour")); // "dalam 2 jam"
// 2. Menggabungkan array menjadi kalimat alami dengan kata hubung "dan" / "atau"
const formatDaftar = new Intl.ListFormat("id-ID", {
style: "long",
type: "conjunction"
});
console.log(formatDaftar.format(["HTML", "CSS", "JavaScript", "PHP"]));
// Keluaran: "HTML, CSS, JavaScript, dan PHP"
IntlMembuat instans new Intl.DateTimeFormat(...) atau new Intl.NumberFormat(...) membutuhkan pembacaan tabel bahasa di awal. Jika Anda memformat 1.000 baris di dalam tabel, buat objek formatter-nya satu kali di luar perulangan, lalu panggil metode .format(...) di dalam perulangan (jauh lebih cepat daripada memanggil .toLocaleString() berulang-ulang di setiap baris!).
3. Masa Depan Tanggal di JavaScript: Mengenal Objek Temporal
Karena objek Date klasik bersifat mutable (memanggil tanggal.setMonth(5) mengubah objek aslinya di tempat!) dan tidak memisahkan konsep "Tanggal Kalender Murni tanpa Jam" dari "Titik Waktu Zona Tertentu", TC39 menghadirkan API global baru bernama Temporal (sudah didukung Chrome/Edge 144+ dan Firefox 139+, tetapi belum Baseline karena Safari belum merilisnya; Node.js 24 juga belum mengaktifkannya secara bawaan):
- Semua objek
Temporalbersifat 100% Immutable (sepertiDateTimeImmutabledi PHP). - Indeks bulan dimulai secara wajar dari
1(Januari) hingga12(Desember)! - Memisahkan tipe dengan tegas:
Temporal.Now.instant()(titik waktu eksak UTC)Temporal.PlainDate.from("2026-10-16")(tanggal kalender murni, misalnya tanggal lahir atau hari libur)Temporal.ZonedDateTime(waktu lengkap dengan zona waktu IANA seperti[Asia/Jakarta]).
// Penggunaan progresif Temporal jika sudah tersedia di lingkungan runtime:
if ("Temporal" in globalThis) {
const hariIni = Temporal.PlainDate.from("2026-10-16");
const mingguDepan = hariIni.add({ days: 7 });
console.log(mingguDepan.toString()); // "2026-10-23" (hariIni tetap utuh "2026-10-16"!)
}
Latihan Praktik: Modul Utilitas Pemformatan Lokal Indonesia
Buatlah berkas lokalisasi-id.js dan jalankan dengan Node.js:
- Buat satu instans
Intl.NumberFormatuntuk Rupiah, satuIntl.DateTimeFormatuntuk zona waktu"Asia/Jakarta", dan satuIntl.ListFormat. - Buat fungsi
formatKartuKursus({ judul, harga, diperbaruiPada, prasyarat })yang mengembalikan objek dengan harga berformat Rupiah, tanggal pembaruan berformat WIB, dan daftar prasyarat yang dirangkai menjadi kalimat Bahasa Indonesia yang rapi.