В работе с датами и временем в JavaScript основная сложность связана с тем, что большинство встроенных представлений времени оперирует целыми числами. Базовая единица — миллисекунда, однако при преобразовании в секунды, минуты и часы часто требуется сохранение точности в виде дробных значений. Библиотека Day.js сохраняет этот подход: внутреннее хранение всегда основано на миллисекундах, а дробная точность формируется на уровне вычислений.
Ключевая особенность заключается в том, что любые дробные значения в Day.js не хранятся напрямую, а вычисляются при преобразованиях и операциях разности.
Метод diff поддерживает возврат дробных значений при
использовании дополнительного параметра точности.
dayjs(end).diff(dayjs(start), 'second', true)
Третий аргумент true включает режим дробного
результата.
Пример:
import dayjs from 'dayjs';
const start = dayjs('2026-01-01T10:00:00.000');
const end = dayjs('2026-01-01T10:00:01.750');
const diffSeconds = end.diff(start, 'second', true);
console.log(diffSeconds); // 1.75
При отключённой точности результат округляется до целого:
end.diff(start, 'second'); // 1
Поддерживаемые единицы для дробных значений включают:
millisecondsecondminutehourdayДробные значения становятся особенно заметны при переходе между единицами.
const start = dayjs('2026-01-01T00:00:00.000');
const end = dayjs('2026-01-01T00:01:30.000');
end.diff(start, 'minute', true); // 1.5
end.diff(start, 'second', true); // 90
end.diff(start, 'hour', true); // 0.025
При этом Day.js всегда вычисляет разницу через миллисекунды, а затем делит на соответствующий коэффициент единицы измерения.
Базовая единица хранения — миллисекунда, поэтому получение дробных значений часто выполняется вручную через деление.
const start = dayjs('2026-01-01T00:00:00.000');
const end = dayjs('2026-01-01T00:00:02.250');
const diffMs = end.valueOf() - start.valueOf();
const diffSeconds = diffMs / 1000;
console.log(diffSeconds); // 2.25
Метод valueOf() возвращает Unix-время в миллисекундах,
что делает его основой для точных вычислений.
Метод unix() возвращает время в секундах, но без дробной
части:
const t = dayjs('2026-01-01T00:00:01.900');
t.unix(); // 1767225601
Любая информация о миллисекундах теряется, поэтому для сохранения
дробной точности используется valueOf():
t.valueOf() / 1000; // 1767225601.9
Таким образом, unix() подходит только для целочисленных
сценариев, тогда как valueOf() — для точных расчётов.
Day.js не предоставляет отдельного API для форматирования дробных секунд, поэтому такие значения формируются вручную.
const start = dayjs('2026-01-01T00:00:00.000');
const end = dayjs('2026-01-01T00:00:03.456');
const seconds = (end.valueOf() - start.valueOf()) / 1000;
const minutes = seconds / 60;
console.log(seconds); // 3.456
console.log(minutes); // 0.0576
При необходимости округления используются стандартные методы Jav * aScript:
const rounded = seconds.toFixed(2); // "3.46"
Плагин duration позволяет работать с временными
интервалами, включая дробные значения, через миллисекунды.
import duration from 'dayjs/plugin/duration';
dayjs.extend(duration);
const d = dayjs.duration(2500); // 2500 мс
console.log(d.seconds()); // 2
console.log(d.milliseconds()); // 500
Для получения дробного значения в секундах используется комбинирование:
const d = dayjs.duration(2500);
const totalSeconds = d.asSeconds();
console.log(totalSeconds); // 2.5
Метод asSeconds() возвращает точное дробное значение,
что делает его основным инструментом для высокоточных расчётов
длительностей.
При обработке временных интервалов с высокой частотой обновления (таймеры, анимации, измерение задержек) дробные значения становятся критически важными.
const start = dayjs();
setTimeout(() => {
const end = dayjs();
const elapsed = end.diff(start, 'second', true);
console.log(elapsed); // например 1.003
}, 1000);
Такая модель позволяет учитывать реальную задержку выполнения, а не только округлённые секунды.
Несмотря на поддержку дробных значений, Day.js опирается на
JavaScript Number, что накладывает ограничения IEEE-754.
При длительных вычислениях возможно появление плавающих
погрешностей:
0.1 + 0.2 // 0.30000000000000004
В контексте Day.js это проявляется при множественных преобразованиях:
const diff = dayjs(end).diff(start, 'second', true);
const shifted = diff * 100;
console.log(shifted);
Для устранения подобных эффектов применяется округление на финальном этапе вычислений.
Дробные значения во времени в Day.js формируются через три основных механизма:
diff(..., true) — дробная разница между датамиvalueOf() — базовое миллисекундное представлениеduration.asX() — точные интервалы через Duration
APIКомбинация этих подходов обеспечивает единый математический слой поверх неизменяемой модели хранения времени в миллисекундах.