Переход с Day.js

Переход с Day.js на Luxon начинается с понимания фундаментального различия архитектур. Day.js ориентирован на минималистичную обёртку над Date с плагинами, тогда как Luxon строит собственную модель времени поверх международного стандарта ICU и нативной поддержки Intl.

Ключевой сдвиг:

  • Day.js → расширяемый микрофреймворк вокруг Date
  • Luxon → полноценная модель DateTime, Duration, Interval

Это приводит к изменению подхода к работе со временем: вместо цепочек плагинов используется единая, строго типизированная модель.


Создание даты и времени

Day.js

import dayjs from "dayjs";

const d = dayjs();
const fromString = dayjs("2026-01-01");

Luxon

import { DateTime } from "luxon";

const dt = DateTime.now();
const fromString = DateTime.fromISO("2026-01-01");

Ключевое различие

Luxon не парсит строки произвольно. Требуется явно указать формат:

DateTime.fromFormat("01-01-2026", "dd-MM-yyyy");

Итог перехода

  • исчезает «магическое» парсирование
  • повышается предсказуемость
  • требуется явное указание формата

Форматы и вывод строк

Day.js

dayjs().format("YYYY-MM-DD HH:mm");

Luxon

DateTime.now().toFormat("yyyy-MM-dd HH:mm");

Отличия синтаксиса

  • YYYYyyyy
  • DDdd
  • HH:mm остаётся аналогичным

Luxon использует форматирование, близкое к Unicode Date Format Patterns.


Работа с UTC и часовыми поясами

Day.js (plugin UTC / timezone)

import utc from "dayjs/plugin/utc";
import timezone from "dayjs/plugin/timezone";

dayjs.extend(utc);
dayjs.extend(timezone);

dayjs().tz("Europe/Paris");

Luxon (встроенная поддержка)

DateTime.now().setZone("Europe/Paris");
DateTime.utc();

Архитектурная разница

Luxon не требует подключения плагинов для базовой работы с зонами времени.


Иммутабельность и цепочки вызовов

Обе библиотеки используют иммутабельные объекты, но Luxon делает это более строго.

Day.js

const d = dayjs();
const updated = d.add(2, "day");

Luxon

const dt = DateTime.now();
const updated = dt.plus({ days: 2 });

Сдвиг модели

  • Day.js: методы с позиционными аргументами
  • Luxon: объектные параметры

Добавление и вычитание времени

Day.js

dayjs().add(3, "hour").subtract(10, "minute");

Luxon

DateTime.now()
  .plus({ hours: 3 })
  .minus({ minutes: 10 });

Важное различие

Luxon исключает строковые единицы измерения, снижая риск ошибок.


Длительности (Duration)

Day.js использует плагин duration, тогда как Luxon имеет встроенную модель.

Luxon Duration

import { Duration } from "luxon";

const dur = Duration.fromObject({ hours: 2, minutes: 30 });

Преобразование

dur.as("minutes"); // 150

Day.js аналог

dayjs.duration(150, "minutes");

Интервалы времени (Interval)

В Day.js отсутствует полноценный аналог.

Luxon Interval

import { Interval, DateTime } from "luxon";

const start = DateTime.now();
const end = start.plus({ days: 5 });

const interval = Interval.fromDateTimes(start, end);

Проверка пересечений

interval.contains(DateTime.now());

Работа с локалями

Day.js

import "dayjs/locale/ru";
dayjs.locale("ru");

Luxon

DateTime.now().setLocale("ru");

Отличие

Luxon опирается на Intl, поэтому поддержка локалей более системная и зависит от окружения.


Относительное время

Day.js (plugin relativeTime)

import relativeTime from "dayjs/plugin/relativeTime";
dayjs.extend(relativeTime);

dayjs().fromNow();

Luxon

DateTime.now().toRelative();

или с базовой точкой:

DateTime.now().toRelative({ base: DateTime.now().minus({ hours: 5 }) });

Парсинг дат: строгая модель Luxon

Day.js допускает гибкое поведение:

dayjs("2026/01/01");

Luxon требует явности:

DateTime.fromFormat("2026/01/01", "yyyy/MM/dd");

Также доступны варианты:

DateTime.fromISO("2026-01-01");
DateTime.fromJSDate(new Date());
DateTime.fromMillis(1700000000000);

Работа с Unix timestamp

Day.js

dayjs(1700000000000);

Luxon

DateTime.fromMillis(1700000000000);

И обратно:

dt.toMillis();

Проверка валидности даты

Day.js

dayjs("invalid").isValid();

Luxon

DateTime.fromISO("invalid").isValid;

Разница:

  • метод → свойство
  • более явная модель состояния

Переход от цепочек плагинов к встроенной функциональности

Day.js требует подключений:

  • utc
  • timezone
  • relativeTime
  • duration
  • isSameOrAfter

Luxon включает всё в ядро:

  • DateTime
  • Duration
  • Interval
  • TimeZone support

Эквиваленты частых операций

Начало и конец дня

Day.js:

dayjs().startOf("day");
dayjs().endOf("day");

Luxon:

DateTime.now().startOf("day");
DateTime.now().endOf("day");

Сравнение дат

Day.js:

dayjs(a).isBefore(b);
dayjs(a).isAfter(b);

Luxon:

a < b;
a > b;

или:

a < b; // сравнение DateTime через valueOf

Особенности миграции бизнес-логики

1. Явное создание объектов

Код с неявным парсингом требует переработки:

Day.js:

dayjs(userInput);

Luxon:

DateTime.fromISO(userInput);
// или fromFormat / fromJSDate

2. Замена строковых единиц

Day.js:

add(1, "month");

Luxon:

plus({ months: 1 });

3. Замена плагинов

Day.js plugin Luxon аналог
utc встроено
timezone setZone
duration Duration
relativeTime toRelative
isSameOrAfter сравнение оператором

Работа с датами JavaScript

Day.js

dayjs(new Date());

Luxon

DateTime.fromJSDate(new Date());

Обратное преобразование:

dt.toJSDate();

Форматирование для API и сериализации

ISO (основной формат Luxon)

dt.toISO();

Альтернативы

dt.toISODate();
dt.toISOTime();
dt.toRFC2822();

Day.js требует форматирования вручную через .format().


Ошибки и диагностика

Luxon предоставляет более строгую модель ошибок:

const dt = DateTime.fromFormat("2026-99-99", "yyyy-MM-dd");

dt.isValid; // false
dt.invalidReason;
dt.invalidExplanation;

Day.js ограничивается булевым флагом.


Типичные проблемы при миграции

1. Неявный парсинг

Day.js допускает некорректные входные данные, Luxon — нет.

2. Форматы строк

Синтаксис форматирования полностью отличается.

3. Отсутствие плагинов

Код с .extend() требует удаления и замены на встроенные API.

4. Работа с зонами времени

Luxon требует явного управления через setZone.


Стратегия постепенного перехода

Часто используется смешанный подход:

import dayjs from "dayjs";
import { DateTime } from "luxon";

const legacy = dayjs(date);
const modern = DateTime.fromJSDate(legacy.toDate());

Обратная конверсия:

const d = DateTime.now().toJSDate();
dayjs(d);

Сопоставление концепций

Концепция Day.js Luxon
Основной объект dayjs() DateTime
Длительность plugin Duration
Интервал отсутствует Interval
Часовые пояса plugin setZone
Форматирование format() toFormat()
Парсинг нестрогий строгий
Локали plugin setLocale

Итоговая модель мышления при переходе

Day.js ориентирует разработку на «удобство по умолчанию», Luxon — на «явность и контроль». Это отражается во всех аспектах:

  • форматирование становится строго типизированным
  • парсинг требует явного указания
  • временные зоны становятся частью основной модели
  • добавляется разделение между датой, длительностью и интервалом

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