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

Отображение точности до долей секунды в форматированных временных интервалах

Введение

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

// Для общего тайминга
new Intl.DurationFormat(locale, {
  style: 'digital',
  fractionalDigits: 2
}).format(duration);
// "0:00:01.23"

// Для точных измерений
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, который стал доступен в марте 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, если он доступен.