SCALE — Build Lab
開発パターン · JAVASCRIPT PATTERN

フォーマットヘルパ集(金額・日付・電話)

CATEGORY開発パターン TYPEJavaScript Pattern EFFORT30〜60分 DIFFICULTY
PRIMARY CODE
ts
export const fmtCurrency = (n: number) => '¥' + Math.round(n).toLocaleString();
export const fmtNumber = (n: number) => n.toLocaleString();
export const fmtPercent = (n: number, decimals = 1) => (n * 100).toFixed(decimals) + '%';

export function fmtDate(d: Date | string | number, fmt = 'YYYY/MM/DD'): string {
  const x = new Date(d);
  return fmt
    .replace('YYYY', String(x.getFullYear()))
    .replace('MM', String(x.getMonth() + 1).padStart(2, '0'))
    .replace('DD', String(x.getDate()).padStart(2, '0'))
    .replace('HH', String(x.getHours()).padStart(2, '0'))
    .replace('mm', String(x.getMinutes()).padStart(2, '0'));
}

export function fmtPhone(s: string): string {
  const d = s.replace(/\D/g, '');
  if (d.length === 11) return d.replace(/(\d{3})(\d{4})(\d{4})/, '$1-$2-$3');
  if (d.length === 10) return d.replace(/(\d{2,3})(\d{3,4})(\d{4})/, '$1-$2-$3');
  return s;
}

export function fmtRelativeTime(d: Date | string | number): string {
  const diff = Date.now() - new Date(d).getTime();
  const sec = Math.floor(diff / 1000);
  if (sec < 60) return 'たった今';
  if (sec < 3600) return Math.floor(sec / 60) + '分前';
  if (sec < 86400) return Math.floor(sec / 3600) + '時間前';
  if (sec < 86400 * 7) return Math.floor(sec / 86400) + '日前';
  return fmtDate(d);
}

export function fmtFileSize(bytes: number): string {
  const units = ['B', 'KB', 'MB', 'GB'];
  let i = 0;
  while (bytes >= 1024 && i < units.length - 1) { bytes /= 1024; i++; }
  return bytes.toFixed(i === 0 ? 0 : 1) + ' ' + units[i];
}
前提条件
Tailwind CSS v4TypeScript 5
USE CASES
  • 任意のダッシュボードに組み込み

フォーマットヘルパ集(金額・日付・電話)

:LiTarget: 用途

頻出のフォーマット関数集。金額・日付・電話・相対時刻・ファイルサイズ。

:LiSparkle: 特徴

  • ¥1,234,567
  • 2026/05/05
  • 03-1234-5678
  • 3分前
  • 1.2 MB

:LiCode: コード(コピペ用)

export const fmtCurrency = (n: number) => '¥' + Math.round(n).toLocaleString();
export const fmtNumber = (n: number) => n.toLocaleString();
export const fmtPercent = (n: number, decimals = 1) => (n * 100).toFixed(decimals) + '%';

export function fmtDate(d: Date | string | number, fmt = 'YYYY/MM/DD'): string {
  const x = new Date(d);
  return fmt
    .replace('YYYY', String(x.getFullYear()))
    .replace('MM', String(x.getMonth() + 1).padStart(2, '0'))
    .replace('DD', String(x.getDate()).padStart(2, '0'))
    .replace('HH', String(x.getHours()).padStart(2, '0'))
    .replace('mm', String(x.getMinutes()).padStart(2, '0'));
}

export function fmtPhone(s: string): string {
  const d = s.replace(/\D/g, '');
  if (d.length === 11) return d.replace(/(\d{3})(\d{4})(\d{4})/, '$1-$2-$3');
  if (d.length === 10) return d.replace(/(\d{2,3})(\d{3,4})(\d{4})/, '$1-$2-$3');
  return s;
}

export function fmtRelativeTime(d: Date | string | number): string {
  const diff = Date.now() - new Date(d).getTime();
  const sec = Math.floor(diff / 1000);
  if (sec < 60) return 'たった今';
  if (sec < 3600) return Math.floor(sec / 60) + '分前';
  if (sec < 86400) return Math.floor(sec / 3600) + '時間前';
  if (sec < 86400 * 7) return Math.floor(sec / 86400) + '日前';
  return fmtDate(d);
}

export function fmtFileSize(bytes: number): string {
  const units = ['B', 'KB', 'MB', 'GB'];
  let i = 0;
  while (bytes >= 1024 && i < units.length - 1) { bytes /= 1024; i++; }
  return bytes.toFixed(i === 0 ? 0 : 1) + ' ' + units[i];
}

:LiHandPointer: 使い方

対象プロジェクトに該当ファイルをコピーして、props を流し込むだけ。

:LiAlertCircle: 注意事項

  • 依存パッケージを忘れず追加