如何在时长显示中包含小数秒

在格式化时间跨度时显示亚秒级精度

简介

当你需要以亚秒级精度显示时长时,就需要展示小数秒。例如,秒表显示 1.234 秒,性能分析器显示加载时间为 0.853 秒,比赛计时器显示完赛时间为 45.678 秒。如果没有正确的格式化,你可能会写出如下代码:

const seconds = 1.234;
const duration = `${seconds}s`;

这样会生成 "1.234s",其中小数点是硬编码的。法国用户会看到 "1.234s",但他们期望的是用逗号分隔的小数 "1,234 s"。不同的地区有不同的小数分隔符和空格规范。

JavaScript 在 fractionalDigits 选项中,通过 Intl.DurationFormat 控制格式化时长时小数秒的显示方式。本教程将介绍如何在时长显示中添加小数秒并控制其精度。

什么是小数秒

小数秒表示小于一秒的时间间隔。1.5 秒表示一秒半,0.250 秒表示四分之一秒。

小数秒有三种形式:

  • 毫秒:千分之一秒(0.001 秒)
  • 微秒:百万分之一秒(0.000001 秒)
  • 纳秒:十亿分之一秒(0.000000001 秒)

fractionalDigits 选项用于控制秒值后显示的小数位数。设置 fractionalDigits: 3 可显示毫秒级精度,设置 fractionalDigits: 6 可显示微秒级精度。

如何格式化不带小数秒的时长

默认情况下,时长格式化只显示整数秒,不包含小数部分。

const duration = { hours: 0, minutes: 0, seconds: 1 };

new Intl.DurationFormat('en', { style: 'long' }).format(duration);
// "1 second"

new Intl.DurationFormat('en', { style: 'digital' }).format(duration);
// "0:00:01"

即使你将毫秒作为单独的单位包含在内,它们也会作为独立单位显示,而不是作为小数秒。

const duration = { seconds: 1, milliseconds: 234 };

new Intl.DurationFormat('en', { style: 'long' }).format(duration);
// "1 second and 234 milliseconds"

此设置会显示两个独立的单位。若要显示 "1.234 秒",需要使用 fractionalDigits 选项。

为持续时间添加小数秒

fractionalDigits 选项用于控制秒数值中显示的小数位数。设置此选项可在输出中包含小数秒。

const duration = { seconds: 1.234 };

new Intl.DurationFormat('en', {
  style: 'long',
  fractionalDigits: 3
}).format(duration);
// "1.234 seconds"

API 会将整数部分和小数部分合并为一个带有本地化小数分隔符的格式化值。

控制小数秒精度

fractionalDigits 选项可接受 0 到 9 之间的值,用于确定小数点后显示的位数。

const duration = { seconds: 1.23456789 };

new Intl.DurationFormat('en', {
  style: 'long',
  fractionalDigits: 0
}).format(duration);
// "1 second"

new Intl.DurationFormat('en', {
  style: 'long',
  fractionalDigits: 2
}).format(duration);
// "1.23 seconds"

new Intl.DurationFormat('en', {
  style: 'long',
  fractionalDigits: 4
}).format(duration);
// "1.2346 seconds"

new Intl.DurationFormat('en', {
  style: 'long',
  fractionalDigits: 6
}).format(duration);
// "1.234568 seconds"

当指定的精度超过可用数字时,格式化器会用零进行补齐。

const duration = { seconds: 1.5 };

new Intl.DurationFormat('en', {
  style: 'long',
  fractionalDigits: 4
}).format(duration);
// "1.5000 seconds"

需要舍入时,格式化器会向零方向舍入。

const duration = { seconds: 1.9999 };

new Intl.DurationFormat('en', {
  style: 'long',
  fractionalDigits: 2
}).format(duration);
// "1.99 seconds"

在数字格式中使用小数秒

数字格式会像计时器一样用冒号分隔各时间单位,小数秒显示在秒数后面。

const duration = { hours: 2, minutes: 30, seconds: 12.345 };

new Intl.DurationFormat('en', {
  style: 'digital',
  fractionalDigits: 3
}).format(duration);
// "2:30:12.345"

new Intl.DurationFormat('en', {
  style: 'digital',
  fractionalDigits: 2
}).format(duration);
// "2:30:12.34"

此方法适用于数字格式下任意时间单位的组合。

const duration = { minutes: 5, seconds: 30.678 };

new Intl.DurationFormat('en', {
  style: 'digital',
  fractionalDigits: 3
}).format(duration);
// "5:30.678"

在不同语言环境下格式化小数秒

不同的语言环境使用不同的小数分隔符。英语使用句点,许多欧洲语言使用逗号。

const duration = { seconds: 1.234 };

new Intl.DurationFormat('en', {
  style: 'long',
  fractionalDigits: 3
}).format(duration);
// "1.234 seconds"

new Intl.DurationFormat('fr', {
  style: 'long',
  fractionalDigits: 3
}).format(duration);
// "1,234 seconde"

new Intl.DurationFormat('de', {
  style: 'long',
  fractionalDigits: 3
}).format(duration);
// "1,234 Sekunden"

new Intl.DurationFormat('ar', {
  style: 'long',
  fractionalDigits: 3
}).format(duration);
// "١٫٢٣٤ ثانية"

API 会根据每个语言环境使用正确的小数分隔符、数字字符和间距。

格式化秒表时间

秒表应用需要以亚秒级精度显示经过时间。请使用带小数秒的数字格式。

function formatStopwatchTime(totalSeconds) {
  const minutes = Math.floor(totalSeconds / 60);
  const seconds = totalSeconds % 60;

  const duration = { minutes, seconds };
  const locale = navigator.language;

  return new Intl.DurationFormat(locale, {
    style: 'digital',
    fractionalDigits: 2
  }).format(duration);
}

formatStopwatchTime(65.47);
// "1:05.47"

formatStopwatchTime(123.89);
// "2:03.89"

此格式会以两位小数显示时间,如 "1:05.47",以实现百分之一秒(厘秒)级精度。

格式化比赛结束时间

体育计时系统以高精度显示完赛时间。比赛结果应使用毫秒级精度。

function formatRaceTime(totalSeconds, locale) {
  const minutes = Math.floor(totalSeconds / 60);
  const seconds = totalSeconds % 60;

  const duration = { minutes, seconds };

  return new Intl.DurationFormat(locale, {
    style: 'digital',
    fractionalDigits: 3
  }).format(duration);
}

formatRaceTime(125.678, 'en');
// "2:05.678"

formatRaceTime(125.678, 'fr');
// "2:05,678"

三位小数表示毫秒级精度,确保比赛计时准确。

格式化性能指标

性能分析器以亚秒级精度显示加载时间和执行时间。应使用带小数秒的简洁格式。

function formatLoadTime(seconds, locale) {
  const duration = { seconds };

  return new Intl.DurationFormat(locale, {
    style: 'short',
    fractionalDigits: 3
  }).format(duration);
}

formatLoadTime(0.853, 'en');
// "0.853 sec"

formatLoadTime(2.145, 'en');
// "2.145 sec"

此格式以紧凑方式显示性能指标,并具备毫秒级精度。

格式化视频帧时间戳

视频编辑应用会显示帧级精度的时间戳。应根据帧率使用带小数秒的格式。

function formatVideoTimestamp(totalSeconds, locale) {
  const hours = Math.floor(totalSeconds / 3600);
  const minutes = Math.floor((totalSeconds % 3600) / 60);
  const seconds = totalSeconds % 60;

  const duration = hours > 0
    ? { hours, minutes, seconds }
    : { minutes, seconds };

  return new Intl.DurationFormat(locale, {
    style: 'digital',
    fractionalDigits: 2
  }).format(duration);
}

formatVideoTimestamp(125.67, 'en');
// "2:05.67"

formatVideoTimestamp(3665.42, 'en');
// "1:01:05.42"

此格式以帧级精度显示 100fps 视频的时间戳。

毫秒转为小数秒

时间计算通常产生毫秒数。将毫秒除以 1000 可转换为小数秒。

const milliseconds = 1234;
const totalSeconds = milliseconds / 1000;

const duration = { seconds: totalSeconds };

new Intl.DurationFormat('en', {
  style: 'long',
  fractionalDigits: 3
}).format(duration);
// "1.234 seconds"

此操作将整数毫秒数转换为小数秒值。

处理极短时长

对于小于 1 秒的时长,仅保留带小数的秒单位。

const duration = { seconds: 0.045 };

new Intl.DurationFormat('en', {
  style: 'short',
  fractionalDigits: 3
}).format(duration);
// "0.045 sec"

小数点前的零表示亚秒级时长。

根据场景选择精度

不同应用场景对精度的要求不同:

  • 秒表:2 位小数(厘秒)
  • 体育计时:3 位小数(毫秒)
  • 性能分析:3 位小数(毫秒)
  • 科学测量:6-9 位小数(微秒到纳秒)

请根据精度需求设置 fractionalDigits 的值。

const duration = { seconds: 1.23456789 };
const locale = navigator.language;

// For general timing
new Intl.DurationFormat(locale, {
  style: 'digital',
  fractionalDigits: 2
}).format(duration);
// "0:00:01.23"

// For precise measurements
new Intl.DurationFormat(locale, {
  style: 'short',
  fractionalDigits: 6
}).format(duration);
// "1.234568 sec"

避免显示超出测量系统精度的数值。

不需要时省略小数秒

设置 fractionalDigits: 0 以仅显示整数秒,不包含任何小数部分。

const duration = { seconds: 1.7 };

new Intl.DurationFormat('en', {
  style: 'long',
  fractionalDigits: 0
}).format(duration);
// "1 second"

这样会对数值进行四舍五入,只显示整数部分。

复用带小数秒的格式化器

为特定精度创建格式化器与其他格式化器的性能优化方式相同。

const formatter = new Intl.DurationFormat('en', {
  style: 'digital',
  fractionalDigits: 3
});

const times = [
  { minutes: 1, seconds: 5.234 },
  { minutes: 2, seconds: 15.678 },
  { minutes: 0, seconds: 45.901 }
];

times.map(t => formatter.format(t));
// ["1:05.234", "2:15.678", "0:45.901"]

这样可以在格式化多个时长时复用格式化器实例,从而提升性能。

浏览器支持

fractionalDigits 选项属于 Intl.DurationFormat API,该 API 于 2025 年 3 月成为 Baseline。它可在最新版 Chrome、Edge、Firefox 和 Safari 浏览器中使用。

在使用小数秒前请先检查兼容性。

if (typeof Intl.DurationFormat !== 'undefined') {
  const formatter = new Intl.DurationFormat('en', {
    style: 'digital',
    fractionalDigits: 3
  });
  return formatter.format(duration);
} else {
  return `${duration.minutes}:${duration.seconds.toFixed(3)}`;
}

这样可以在支持原生 API 时使用原生方法,同时为旧版浏览器提供回退方案。