JavaScript中格式化数字与日期的常用方法

作者:工具松鼠

时间:2026-10-30

浏览:649

全面讲解在JavaScript中格式化数字与日期的常用方法,涵盖原生Intl国际化API、内置方法、自定义模板函数及实际开发中的避坑指南。

文章目录

在前端与 Node.js 业务开发中,将原始的数字(金额、百分比、千分位数值)和日期(时间戳、Date 对象)转换为用户友好的排版格式是高频需求。现代 JavaScript 提供了功能强大的国际化标准 API(Intl.NumberFormat 与 Intl.DateTimeFormat),它们属于原生内置支持,具备极佳的运行性能与跨语言环境能力;同时,结合适度的原生原型方法与轻量模板函数,即可覆盖从高精度财务报表到日常界面展示的绝大多数格式化场景。

一、JavaScript 中格式化数字的核心方法

处理数字展示时,常见需求包括:保留固定小数位、添加千分位分隔符、格式化为法币符号、转换为百分比或缩写大数值。实现方式主要分为原生 Intl.NumberFormat、数值原型方法与自定义正则处理。

1. 使用 Intl.NumberFormat(现代标准方案)

Intl.NumberFormat 是 ECMAScript 国际化 API 规范的一部分。它支持根据指定区域(Locale)自动应用排版规则,例如中文千分位用逗号、德语使用点号等,且原生支持货币与百分比格式化。

// 基础千分位格式化
const num = 1234567.89;
const standardFormatter = new Intl.NumberFormat('zh-CN');
console.log(standardFormatter.format(num));

// 货币格式化:人民币与美元
const cnyFormatter = new Intl.NumberFormat('zh-CN', {
  style: 'currency',
  currency: 'CNY',
  minimumFractionDigits: 2
});
console.log(cnyFormatter.format(num));

const usdFormatter = new Intl.NumberFormat('en-US', {
  style: 'currency',
  currency: 'USD'
});
console.log(usdFormatter.format(num));

// 百分比格式化
const ratio = 0.2856;
const percentFormatter = new Intl.NumberFormat('zh-CN', {
  style: 'percent',
  minimumFractionDigits: 1,
  maximumFractionDigits: 2
});
console.log(percentFormatter.format(ratio));

// 大数值紧凑缩写(如:1.2万 / 1.2M)
const compactFormatter = new Intl.NumberFormat('zh-CN', {
  notation: 'compact'
});
console.log(compactFormatter.format(12500000));
示例输出:
1,234,567.89
¥1,234,567.89
$1,234,567.89
28.56%
1250万

2. 使用 toFixed 与 toLocaleString 原生方法

Number.prototype.toFixed() 常用于快速截断并保留指定小数位数,返回字符串。但需注意它遵循的是“舍入到最近的偶数”(银行家舍入法)以及浮点数存储偏差,在严格四舍五入要求下需要辅助逻辑。

const price = 45.678;
// 保留两位小数
console.log(price.toFixed(2));

// 直接调用 Number.prototype.toLocaleString()
const balance = 9876543.21;
console.log(balance.toLocaleString('zh-CN', { minimumFractionDigits: 2 }));
示例输出:
45.68
9,876,543.21

3. 正则表达式实现轻量千分位

在不引入外部库且仅需要简单千分位分割的轻量场景下,可以使用前瞻断言正则表达式完成转换:

function formatThousands(num) {
  if (num === null || num === undefined || isNaN(num)) return '0';
  const parts = num.toString().split('.');
  parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ',');
  return parts.join('.');
}

console.log(formatThousands(88481234.56));
示例输出: 88,481,234.56
JavaScript中格式化数字与日期的常用方法
图 1:Intl.NumberFormat 选项配置模型与数据流向结构

二、数字格式化规范流程与执行步骤

在企业级业务系统(如后台对账、订单报表)中,直接调用未封装的方法容易遇到 null 报错、NaN 脏数据或频繁实例化导致的性能抖动。规范的操作步骤应当建立完备的校验与实例复用机制。

JavaScript中格式化数字与日期的常用方法
图 2:数字格式化操作步骤与工程执行流程

可复用的生产级数字格式化封装函数

// 实例缓存池,避免高频调用时的性能损耗
const numberFormatterPool = new Map();

function formatCurrency(amount, currency = 'CNY', decimals = 2) {
  if (amount === null || amount === undefined || isNaN(Number(amount))) {
    return '--';
  }

  const cacheKey = `${currency}_${decimals}`;
  if (!numberFormatterPool.has(cacheKey)) {
    numberFormatterPool.set(
      cacheKey,
      new Intl.NumberFormat('zh-CN', {
        style: 'currency',
        currency: currency,
        minimumFractionDigits: decimals,
        maximumFractionDigits: decimals
      })
    );
  }

  return numberFormatterPool.get(cacheKey).format(Number(amount));
}

console.log(formatCurrency(899.5));
console.log(formatCurrency(null));
示例输出:
¥899.50
--

三、JavaScript 中格式化日期的常用方法

日期时间格式化的核心是把时间戳(毫秒/秒)或 Date 对象转成符合具体语境的文本(如 2026-10-24 12:00:00 或 2026年10月24日 星期六)。

1. 使用 Intl.DateTimeFormat(推荐原生标准)

与数字格式化类似,Intl.DateTimeFormat 原生支持设置年份、月份、日期、星期、12/24小时制以及时区参数(timeZone)。

const now = new Date('2026-10-24T12:08:29Z');

// 常见中文日期长格式
const dtfCn = new Intl.DateTimeFormat('zh-CN', {
  year: 'numeric',
  month: 'long',
  day: 'numeric',
  weekday: 'long',
  hour: '2-digit',
  minute: '2-digit',
  second: '2-digit',
  hour12: false
});
console.log(dtfCn.format(now));

// 跨时区展示:指定转换为纽约时间 (America/New_York)
const dtfNy = new Intl.DateTimeFormat('en-US', {
  timeZone: 'America/New_York',
  dateStyle: 'medium',
  timeStyle: 'short'
});
console.log(dtfNy.format(now));
示例输出:
2026年10月24日星期六 20:08:29(依本地时区转换结果)
Oct 24, 2026, 8:08 AM

2. 使用 Date 原生简便方法

对于无需复杂配置的小型项目,原生 Date 对象的自带方法非常轻便:

  • date.toISOString():返回 ISO-8601 标准零时区格式(如 2026-10-24T12:08:29.000Z),适合接口持久化。
  • date.toLocaleDateString():输出符合系统语言的纯日期部分。
  • date.toLocaleTimeString():输出符合系统语言的纯时间部分。

3. 轻量级通用模板替换函数(无依赖)

许多中文业务场景严格要求输出 YYYY-MM-DD HH:mm:ss 形式。通过简单的正则字典替换,无需引入大型外部日期库即可实现:

function formatDate(input, format = 'YYYY-MM-DD HH:mm:ss') {
  const d = input instanceof Date ? input : new Date(input);
  if (isNaN(d.getTime())) return '';

  const pad = (n) => String(n).padStart(2, '0');

  const map = {
    YYYY: d.getFullYear(),
    MM: pad(d.getMonth() + 1),
    DD: pad(d.getDate()),
    HH: pad(d.getHours()),
    mm: pad(d.getMinutes()),
    ss: pad(d.getSeconds())
  };

  return format.replace(/YYYY|MM|DD|HH|mm|ss/g, (matched) => map[matched]);
}

const testDate = new Date(1761278909000);
console.log(formatDate(testDate, 'YYYY-MM-DD HH:mm:ss'));
console.log(formatDate(testDate, 'YYYY/MM/DD'));
示例输出:
2025-10-24 12:08:29
2025/10/24
JavaScript中格式化数字与日期的常用方法
图 3:日期时间数据从原始时刻到多维度呈现的处理管道

四、方案对比与选型决策指南

面对不同的业务体量和场景特征,开发者应当根据项目依赖预算、性能要求以及本地化需求选择合适的技术路径:

技术方案 适用场景 主要优势 局限与注意事项
Intl.NumberFormat 国际化货币、百分比、大数缩写、标准化千分位 现代浏览器原生标准、无需引入三方库、多语言支持完备 旧版本 IE 不支持;在循环中频繁 new 会产生性能开销(应复用实例)
Intl.DateTimeFormat 跨时区时间转换、本地化星期/月份排版、相对时间 原生时区数据库换算、支持长/短/完整日期风格 对非常规自定义格式(如仅替换指定占位符)配置稍显繁琐
toFixed / 正则千分位 单一数字截断、国内后台简单表格排版 轻便快速、代码极短、执行无额外抽象层 存在浮点数舍入偏差;不支持语言环境自适应
手写 formatDate 模板函数 固定的 YYYY-MM-DD HH:mm:ss 业务展示 零打包体积、行为稳定透明、可控性极高 不具备时区转换能力,依赖当前运行宿主本地时间
三方轻量库 (Day.js 等) 涉及复杂时间加减、比较、区间计算与复杂相对时间 API 链式调用友好、生态插件丰富(约 2KB) 增加项目外部依赖;若仅展示日期则可能造成性能冗余
JavaScript中格式化数字与日期的常用方法
图 4:数字与日期格式化技术选型决策树与实践建议

五、常见陷阱与工程最佳实践

注意:浮点数精度与四舍五入偏差

JavaScript 使用 IEEE 754 双精度浮点数存储,因此 0.1 + 0.2 !== 0.3,而 1.005.toFixed(2) 会意外输出 "1.00" 而不是 "1.01"。在金融计费等高精度场景中,金额应在后端统一以最小货币单位(如“分”)存储为整数,或前端使用定点运算辅助库,再进行最终展示层格式化。

为了保障生产代码的稳健性,建议在实际项目中遵守以下三项工程规范:

  1. 防御性空值处理:在格式化函数入口处统一判断 null、undefined、空字符串与 NaN,并约定统一的占位符号(如 "--" 或 "0.00"),防止页面崩溃。
  2. 时区显式声明:在多地区协作或国际化项目中,接口传输的时间统一采用 UTC 时间戳或携带时区偏移的 ISO 字符串(如 2026-10-24T04:08:29Z),客户端渲染时若需固定为北京时间,必须显式传入 timeZone: 'Asia/Shanghai',切勿依赖用户本机的操作系统时区设置。
  3. 重用 Intl 实例:构造 Intl.NumberFormat 或 Intl.DateTimeFormat 的耗时明显高于普通函数调用。在长表格、大数据看板渲染时,必须通过缓存池单例复用实例,可大幅减少垃圾回收与构造开销。

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章