Use Cases

Mengimplementasikan Currency Formatting dengan Claude Code

Learn about implementing currency formatting using Claude Code. Includes practical code examples.

通貨format dengan Claude Code: 正しくimplementasi

ECサイト、会計aplikasi、国際dukunganservice 、通貨 正確なformat 不可欠.小数点、桁区切り、通貨記号 ルール 国・通貨ご dan 異なる untuk 、自前 format dan 不具合 温床 なり.Claude Code 使えば、Intl.NumberFormatや専用library pemanfaatan robustなimplementasi efisien pembangunan bisa dilakukan.

pemanfaatan Intl.NumberFormat

> 多通貨dukungan 通貨formatutilitas buatkan.
> 日本円、USドル、ユーロ support.
> ロケール別tampilan、為替konversi、金額 validasi juga 含めて。
// src/lib/currency.ts

export type CurrencyCode = 'JPY' | 'USD' | 'EUR' | 'GBP' | 'CNY' | 'KRW';

interface FormatOptions {
  currency: CurrencyCode;
  locale?: string;
  compact?: boolean;      // "1.2万" ような短縮tampilan
  showSign?: boolean;     // +/- 符号 tampilan
}

/**
 * 通貨をフォーマットする
 */
export function formatCurrency(
  amount: number,
  options: FormatOptions
): string {
  const { currency, locale = 'en-US', compact = false, showSign = false } = options;

  const formatter = new Intl.NumberFormat(locale, {
    style: 'currency',
    currency,
    notation: compact ? 'compact' : 'standard',
    signDisplay: showSign ? 'exceptZero' : 'auto',
    // 小数通貨 小数点2桁、JPY/KRW 0桁(自動判定)
  });

  return formatter.format(amount);
}

// Usage example
formatCurrency(1234567, { currency: 'JPY' });          // "¥1,234,567"
formatCurrency(1234.56, { currency: 'USD' });           // "$1,234.56"
formatCurrency(1234.56, { currency: 'EUR', locale: 'de-DE' }); // "1.234,56 €"
formatCurrency(1234567, { currency: 'JPY', compact: true });    // "¥123万"

hal yang perlu diperhatikan 通貨計算

// src/lib/currency-math.ts

/**
 * 浮動小数点の誤差を避けるため、整数(最小通貨単位)で計算する
 * JPY: 1円 = 1 | USD: 1セント = 1 | EUR: 1セント = 1
 */
export class Money {
  constructor(
    private readonly amountInMinorUnit: number,
    private readonly currency: CurrencyCode
  ) {}

  // セント/円 小数桁数
  private static decimals(currency: CurrencyCode): number {
    return ['JPY', 'KRW'].includes(currency) ? 0 : 2;
  }

  static fromMajorUnit(amount: number, currency: CurrencyCode): Money {
    const decimals = Money.decimals(currency);
    const minor = Math.round(amount * Math.pow(10, decimals));
    return new Money(minor, currency);
  }

  toMajorUnit(): number {
    const decimals = Money.decimals(this.currency);
    return this.amountInMinorUnit / Math.pow(10, decimals);
  }

  add(other: Money): Money {
    this.assertSameCurrency(other);
    return new Money(this.amountInMinorUnit + other.amountInMinorUnit, this.currency);
  }

  subtract(other: Money): Money {
    this.assertSameCurrency(other);
    return new Money(this.amountInMinorUnit - other.amountInMinorUnit, this.currency);
  }

  multiply(factor: number): Money {
    return new Money(Math.round(this.amountInMinorUnit * factor), this.currency);
  }

  format(locale?: string): string {
    return formatCurrency(this.toMajorUnit(), { currency: this.currency, locale });
  }

  private assertSameCurrency(other: Money) {
    if (this.currency !== other.currency) {
      throw new Error(`通貨 異なります: ${this.currency} と ${other.currency}`);
    }
  }
}

// Usage example
const price = Money.fromMajorUnit(1980, 'JPY');
const tax = price.multiply(0.1);
const total = price.add(tax);
console.log(total.format()); // "¥2,178"

為替レートkonversi

// src/lib/exchange.ts
interface ExchangeRates {
  base: CurrencyCode;
  rates: Record<CurrencyCode, number>;
  updatedAt: string;
}

let cachedRates: ExchangeRates | null = null;

export async function getExchangeRates(base: CurrencyCode = 'JPY'): Promise<ExchangeRates> {
  // cache 1時間以内なら再pemanfaatan
  if (cachedRates && Date.now() - new Date(cachedRates.updatedAt).getTime() < 3600000) {
    return cachedRates;
  }

  const res = await fetch(`https://api.exchangerate-api.com/v4/latest/${base}`);
  const data = await res.json();

  cachedRates = {
    base,
    rates: data.rates,
    updatedAt: new Date().toISOString(),
  };

  return cachedRates;
}

export async function convertCurrency(
  amount: number,
  from: CurrencyCode,
  to: CurrencyCode
): Promise<{ converted: number; rate: number }> {
  const rates = await getExchangeRates(from);
  const rate = rates.rates[to];

  return {
    converted: Math.round(amount * rate * 100) / 100,
    rate,
  };
}

通貨inputkomponen

// src/components/CurrencyInput.tsx
'use client';
import { useState } from 'react';

interface Props {
  value: number;
  currency: CurrencyCode;
  onChange: (value: number) => void;
}

export function CurrencyInput({ value, currency, onChange }: Props) {
  const [displayValue, setDisplayValue] = useState(value.toLocaleString());

  const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const raw = e.target.value.replace(/[^0-9.-]/g, '');
    setDisplayValue(e.target.value);
    const num = parseFloat(raw);
    if (!isNaN(num)) onChange(num);
  };

  const handleBlur = () => {
    setDisplayValue(value.toLocaleString());
  };

  const symbol = new Intl.NumberFormat('en-US', {
    style: 'currency',
    currency,
    currencyDisplay: 'narrowSymbol',
  }).formatToParts(0).find((p) => p.type === 'currency')?.value || '';

  return (
    <div className="relative">
      <span className="absolute left-3 top-1/2 -translate-y-1/2 text-gray-400">{symbol}</span>
      <input
        type="text"
        value={displayValue}
        onChange={handleChange}
        onBlur={handleBlur}
        className="w-full border rounded-lg pl-8 pr-4 py-2 text-right"
        inputMode="decimal"
      />
    </div>
  );
}

落とし穴 浮動小数点

JavaScript 0.1 + 0.2 === 0.30000000000000004 dan なるmasalah 有名.通貨計算 必ず最小単位(セント/円) 整数 扱い、tampilan時 み小数 konversi 鉄則.

Artikel Terkait

Untuk 日付のformatは日付・時間の扱い、国際化全般, lihat i18n実装ガイド.

Intl.NumberFormat 詳細仕様 MDN(developer.mozilla.org/Intl/NumberFormat) konfirmasi bisa dilakukan.

#Claude Code #currency #format #Intl #internationalization