Date, Number & Currency Formatting
Format tanggal, angka, dan mata uang berbeda drastis antar locale. Hardcoding format adalah salah satu kesalahan i18n paling umum.
Perbedaan Format per Region
| Data | US (en-US) | Indonesia (id-ID) | Germany (de-DE) | Japan (ja-JP) |
|---|---|---|---|---|
| Tanggal | 04/16/2026 | 16/04/2026 | 16.04.2026 | 2026/04/16 |
| Angka | 1,234.56 | 1.234,56 | 1.234,56 | 1,234.56 |
| Mata Uang | $1,234.56 | Rp1.234,56 | 1.234,56 € | ¥1,235 |
Date Formatting Best Practices
// ❌ JANGAN hardcode format
function formatDate(date) {
return `${date.getMonth()+1}/${date.getDate()}/${date.getFullYear()}`;
}
// ✅ Gunakan Intl API
function formatDate(date, locale = "id-ID") {
return new Intl.DateTimeFormat(locale, {
year: "numeric",
month: "long",
day: "numeric",
}).format(date);
}
formatDate(new Date("2026-04-16"), "id-ID") // "16 April 2026"
formatDate(new Date("2026-04-16"), "en-US") // "April 16, 2026"
formatDate(new Date("2026-04-16"), "ja-JP") // "2026年4月16日"
Relative Time
function timeAgo(date, locale = "id") {
const rtf = new Intl.RelativeTimeFormat(locale, { numeric: "auto" });
const diff = (date - new Date()) / 1000; // seconds
const units = [
{ unit: "year", seconds: 31536000 },
{ unit: "month", seconds: 2592000 },
{ unit: "week", seconds: 604800 },
{ unit: "day", seconds: 86400 },
{ unit: "hour", seconds: 3600 },
{ unit: "minute", seconds: 60 },
{ unit: "second", seconds: 1 },
];
for (const { unit, seconds } of units) {
if (Math.abs(diff) >= seconds) {
return rtf.format(Math.round(diff / seconds), unit);
}
}
return rtf.format(0, "second");
}
timeAgo(oneDayAgo, "id") // "kemarin"
timeAgo(oneDayAgo, "en") // "yesterday"
Currency dengan react-intl
import { FormattedNumber } from "react-intl";
// Otomatis format sesuai locale aktif
<FormattedNumber
value={150000}
style="currency"
currency="IDR"
minimumFractionDigits={0}
/>
// locale "id-ID" → "Rp 150.000"
// locale "en-US" → "IDR 150,000"
Timezone Handling
// Selalu simpan waktu dalam UTC di server
const utcDate = new Date().toISOString(); // "2026-04-16T10:30:00.000Z"
// Tampilkan sesuai timezone user
new Intl.DateTimeFormat("id-ID", {
timeZone: "Asia/Jakarta", // WIB
hour: "2-digit",
minute: "2-digit",
timeZoneName: "short",
}).format(new Date(utcDate))
// "17.30 WIB"
// Deteksi timezone user
const userTimezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
// "Asia/Jakarta"
Number Formatting di Backend (Laravel)
// PHP NumberFormatter
$fmt = new NumberFormatter("id_ID", NumberFormatter::CURRENCY);
echo $fmt->formatCurrency(150000, "IDR");
// "Rp150.000,00"
$fmt = new NumberFormatter("de_DE", NumberFormatter::DECIMAL);
echo $fmt->format(1234567.89);
// "1.234.567,89"