Date, Number & Currency Formatting — i18n

Date, Number & Currency Formatting Format tanggal, angka, dan mata uang berbeda drastis antar locale. Hardcoding format adalah salah satu kesalahan i18n paling

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

DataUS (en-US)Indonesia (id-ID)Germany (de-DE)Japan (ja-JP)
Tanggal04/16/202616/04/202616.04.20262026/04/16
Angka1,234.561.234,561.234,561,234.56
Mata Uang$1,234.56Rp1.234,561.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"

Yang akan kamu pelajari