API Intl pada JavaScript menyediakan pemformatan tanggal, angka, daftar, dan waktu relatif yang mengikuti locale pembaca. Aplikasi Node yang melayani pengguna dari beberapa wilayah perlu API ini agar keluaran tidak ditulis dengan asumsi locale server. Node versi 13 ke atas dikirim dengan full-icu secara default, sehingga seluruh locale yang didukung ICU tersedia tanpa instalasi tambahan. Setelah membaca topik ini, pembaca dapat memformat tanggal dan angka dengan Intl.DateTimeFormat serta Intl.NumberFormat, memahami peran locale pada pemformatan, serta memeriksa ketersediaan ICU pada Node yang dipasang di production.
Locale dan pemformatan#
Locale adalah penanda wilayah dan bahasa seperti id-ID untuk Bahasa Indonesia di Indonesia atau en-US untuk English di Amerika Serikat. Locale menentukan elemen pemformatan yang bergantung pada konvensi wilayah, yaitu urutan hari-bulan-tahun pada tanggal, pemisah desimal dan ribuan pada angka, serta nama hari dan bulan. API Intl mengambil locale sebagai argumen string pertama dan menghasilkan keluaran yang mengikuti konvensi locale tersebut.
const tanggal = new Date('2026-11-02T10:30:00');
const idDate = new Intl.DateTimeFormat('id-ID', { dateStyle: 'full', timeStyle: 'short' }).format(tanggal);
const enDate = new Intl.DateTimeFormat('en-US', { dateStyle: 'full', timeStyle: 'short' }).format(tanggal);
console.log('id-ID:', idDate);
console.log('en-US:', enDate);
const angka = 1234567.89;
const idDecimal = new Intl.NumberFormat('id-ID').format(angka);
const enDecimal = new Intl.NumberFormat('en-US').format(angka);
console.log('id-ID:', idDecimal);
console.log('en-US:', enDecimal);
const daftar = new Intl.ListFormat('id-ID', { style: 'long', type: 'conjunction' }).format(['ali', 'budi', 'citra']);
console.log('daftar:', daftar);
const relatif = new Intl.RelativeTimeFormat('id-ID', { numeric: 'auto' }).format(-1, 'day');
console.log('relatif:', relatif);id-ID: Senin, 02 November 2026 pukul 10.30
en-US: Monday, November 2, 2026 at 10:30 AM
id-ID: 1.234.567,89
en-US: 1,234,567.89
daftar: ali, budi, dan citra
relatif: kemarinPemformatan tanggal dengan locale id-ID menghasilkan nama hari Senin, nama bulan November, dan pemisah waktu pukul dengan format 10.30. Locale en-US menghasilkan nama hari Monday, nama bulan November, dan pemisah waktu at dengan format 10:30 AM. Perbedaan ini bukan sekadar terjemahan kata, melainkan konvensi susunan: id-ID memakai DD Month YYYY sementara en-US memakai Month DD, YYYY.
Pemformatan angka dengan locale id-ID menghasilkan 1.234.567,89, yaitu . sebagai pemisah ribuan dan , sebagai pemisah desimal. Locale en-US menghasilkan 1,234,567.89 dengan kebalikan pemisah. Pemformatan ini penting karena angka yang ditampilkan tanpa memperhitungkan locale dapat membingungkan pembaca. Contoh yang sering muncul adalah 1,234: pada konvensi en-US koma adalah pemisah ribuan sehingga nilainya seribu dua ratus tiga puluh empat, sedangkan pada konvensi id-ID koma adalah pemisah desimal sehingga nilainya satu koma dua tiga empat.
DateTimeFormat dan NumberFormat#
Intl.DateTimeFormat(locale, options) membuat pemformat tanggal dengan opsi seperti dateStyle (full, long, medium, short) dan timeStyle dengan nilai yang sama. Opsi dateStyle: 'full' menghasilkan hari, tanggal, bulan, tahun, dan untuk locale Indonesia disertai kata pukul sebelum waktu. Opsi lain seperti weekday, year, month, day, hour, minute dapat dipakai untuk memilih bagian yang ditampilkan tanpa memakai style baku.
Intl.NumberFormat(locale, options) membuat pemformat angka. Opsi style menentukan jenis pemformatan: 'decimal' (default) untuk angka biasa, 'currency' untuk mata uang dengan field currency tambahan, 'unit' untuk satuan seperti kilometer-per-hour, dan 'percent' untuk persentase. Opsi minimumFractionDigits dan maximumFractionDigits mengatur jumlah angka di belakang koma. Pemakaian currency menghasilkan simbol mata uang yang sesuai dengan locale, namun simbol sering diikuti non-breaking space yang membuat perbandingan teks menjadi halus.
ListFormat dan RelativeTimeFormat#
Intl.ListFormat(locale, options) memformat larik string menjadi daftar dengan konjungsi yang sesuai dengan locale. Opsi style (long, short, narrow) dan type (conjunction, disjunction, unit) menentukan bentuk daftar. Locale id-ID dengan type: 'conjunction' menghasilkan ali, budi, dan citra, sedangkan type: 'disjunction' menghasilkan ali, budi, atau citra. Pemformatan ini berguna untuk pesan yang memuat daftar nama atau item yang panjangnya dinamis.
Intl.RelativeTimeFormat(locale, options) memformat selisih waktu relatif seperti kemarin atau dua hari yang lalu. Opsi numeric (always atau auto) menentukan apakah selisih satu selalu ditampilkan sebagai angka (1 hari yang lalu) atau sebagai kata (kemarin). Pemakaian numeric: 'auto' menghasilkan keluaran yang lebih alami, sedangkan numeric: 'always' menghasilkan keluaran yang dapat diurutkan dan diproses mesin.
Ketersediaan ICU#
Node versi 13 ke atas dikirim dengan full-icu secara default, yaitu seluruh data ICU disertakan pada binari Node. Node versi lama dikirim dengan small-icu yang hanya mendukung locale en-US penuh dan locale lain dengan fallback. Pada Node dengan small-icu, pemanggilan Intl.DateTimeFormat('id-ID', ...) tetap berjalan tetapi mungkin menghasilkan keluaran yang setengah locale, misalnya nama bulan January (Inggris) alih-alih Januari (Indonesia) atau nama hari Monday alih-alih Senin.
Pemeriksaan ketersediaan ICU dilakukan dengan beberapa cara. Pemanggilan process.config.variables.icu_data_file_length memberi indikasi ukuran data ICU yang dimuat, dan pemeriksaan Intl.DateTimeFormat.supportedLocalesOf(['id-ID', 'ja-JP']) mengembalikan daftar locale yang didukung penuh. Pada Node 24 LTS yang dipakai pada topik ini, full-icu aktif sehingga seluruh locale yang didukung ICU tersedia.
Kesalahan umum#
Kesalahan yang sering muncul adalah memformat tanggal dan angka dengan toString() atau String() lalu mengirimkannya ke pengguna di locale yang berbeda. Keluaran tanggal.toString() mengikuti locale server (default en-US), sehingga pengguna Indonesia melihat Mon Nov 02 2026 yang tidak mengikuti konvensi lokal. Perbaikannya adalah selalu memakai Intl.DateTimeFormat dengan locale yang dipilih berdasarkan preferensi pengguna.
Kesalahan lain adalah menganggap pemformatan angka dengan Number.prototype.toLocaleString() cukup. Metode ini memang memakai Intl secara internal, tetapi locale default yang dipakai berasal dari sistem operasi, sehingga hasilnya dapat berbeda antar mesin. Pemakaian Intl.NumberFormat dengan locale eksplisit menghasilkan keluaran yang konsisten terlepas dari mesin tempat aplikasi berjalan.
Ringkasan#
- API
Intlmemformat tanggal, angka, daftar, dan waktu relatif mengikuti locale. Localeid-IDmenghasilkan nama hariSenin, pemisah waktupukul, pemisah ribuan., dan pemisah desimal,. Intl.DateTimeFormatmemakaidateStyledantimeStyle, sedangkanIntl.NumberFormatmemakaistylesepertidecimal,currency, danunitdengan opsi pecahan.Intl.ListFormatmemformat larik dengan konjungsi atau disjungsi, sedangkanIntl.RelativeTimeFormatmemformat selisih waktu seperti kemarin dengan opsinumeric: 'auto'.- Node 13 ke atas dikirim dengan full-icu, sehingga seluruh locale tersedia. Pada container ringkas seperti Alpine, paket
icu-data-fullmungkin perlu dipasang terpisah.
Referensi#
- Intl — Node.js
— Referensi resmi tentang API
Intlpada Node, termasuk full-icu dan cara pemeriksaan ketersediaan ICU. - Intl.DateTimeFormat — MDN
— Opsi
dateStyle,timeStyle, dan pemakaian locale pada pemformatan tanggal. - Intl.NumberFormat — MDN
— Opsi
style,currency, danminimumFractionDigitsuntuk pemformatan angka.