Как добавить дробные секунды в отображение длительности

Показать точность до долей секунды в форматированных промежутках времени

Введение

Если вы хотите показывать длительность с точностью до долей секунды, нужно отображать дробные секунды. Секундомер показывает 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"

Это показывает временные метки с точностью до кадра для видео со 100 кадрами в секунду.

Преобразование миллисекунд в дробные секунды

Вычисления времени часто дают результат в миллисекундах. Преобразуйте миллисекунды в дробные секунды, разделив на 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"

Это преобразует целые миллисекунды в значение дробных секунд.

Обработка очень коротких длительностей

Для длительностей меньше одной секунды указывайте только секунды с дробными знаками.

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 является частью API Intl.DurationFormat, который стал Baseline в марте 2025 года. Она работает в последних версиях 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, если он доступен.