Форматирование дат и чисел

Preact как легковесная альтернатива React предоставляет разработчикам возможность создавать интерфейсы с высокой производительностью. При работе с данными часто возникает необходимость форматировать даты и числа для отображения в UI. В отличие от крупных библиотек, Preact не содержит встроенных средств для локализации и форматирования, поэтому для этого используются стандартные возможности JavaScript и сторонние библиотеки.


Форматирование дат

В JavaScript для работы с датами применяется объект Date и встроенный API Intl.DateTimeFormat. Preact компоненты могут использовать их напрямую в JSX.

Пример базового форматирования даты:

import { h } from 'preact';

const DateDisplay = ({ date }) => {
  const formattedDate = new Intl.DateTimeFormat('ru-RU', {
    year: 'numeric',
    month: 'long',
    day: 'numeric',
    weekday: 'long',
    hour: '2-digit',
    minute: '2-digit'
  }).format(new Date(date));

  return <div>{formattedDate}</div>;
};

export default DateDisplay;

В этом примере:

  • ru-RU задает русскую локализацию.
  • month: 'long' выводит полное название месяца.
  • weekday: 'long' добавляет день недели.
  • hour и minute форматируют время в 2-значном формате.

Динамическое обновление даты в компоненте:

import { h } from 'preact';
import { useState, useEffect } from 'preact/hooks';

const Clock = () => {
  const [time, setTime] = useState(new Date());

  useEffect(() => {
    const timer = setInterval(() => setTime(new Date()), 1000);
    return () => clearInterval(timer);
  }, []);

  const formattedTime = new Intl.DateTimeFormat('ru-RU', {
    hour: '2-digit',
    minute: '2-digit',
    second: '2-digit'
  }).format(time);

  return <div>{formattedTime}</div>;
};

export default Clock;

Здесь используется хук useEffect для установки интервала обновления времени каждую секунду. В Preact он работает аналогично React, обеспечивая реактивное обновление компонента.


Форматирование чисел

Для чисел применяется объект Intl.NumberFormat. Он позволяет задавать локализацию, стиль отображения (десятичный, валютный, процентный) и точность.

Пример форматирования валюты:

import { h } from 'preact';

const Price = ({ amount }) => {
  const formattedPrice = new Intl.NumberFormat('ru-RU', {
    style: 'currency',
    currency: 'RUB',
    minimumFractionDigits: 2,
    maximumFractionDigits: 2
  }).format(amount);

  return <span>{formattedPrice}</span>;
};

export default Price;

Ключевые моменты:

  • style: 'currency' указывает формат валюты.
  • currency: 'RUB' задает российский рубль.
  • minimumFractionDigits и maximumFractionDigits контролируют количество знаков после запятой.

Форматирование процентов:

import { h } from 'preact';

const Discount = ({ value }) => {
  const formattedPercent = new Intl.NumberFormat('ru-RU', {
    style: 'percent',
    minimumFractionDigits: 0,
    maximumFractionDigits: 2
  }).format(value);

  return <span>{formattedPercent}</span>;
};

export default Discount;

Здесь value должен быть в виде десятичной дроби (например, 0.15 для 15%). Этот подход позволяет избежать ручных вычислений и ошибок при отображении процентов.


Локализация и сторонние библиотеки

Для сложных сценариев форматирования дат и чисел, включая поддержку нескольких языков, часто используют сторонние библиотеки:

  • date-fns — предоставляет функции для форматирования и манипуляций с датами.
  • luxon — мощная библиотека для работы с датами и временем с поддержкой таймзон.
  • numeral.js — для кастомного форматирования чисел и валют.
  • Intl API — встроенный в браузеры стандарт, который покрывает большинство простых задач без подключения библиотек.

Пример с date-fns:

import { h } from 'preact';
import { format } from 'date-fns';
import { ru } from 'date-fns/locale';

const DateFormatted = ({ date }) => {
  return <div>{format(new Date(date), "d MMMM yyyy, EEEE", { locale: ru })}</div>;
};

export default DateFormatted;

Использование date-fns позволяет гибко форматировать даты, учитывать локализацию и делать форматирование более читаемым.


Рекомендации по использованию

  • Для простых задач достаточно Intl.DateTimeFormat и Intl.NumberFormat, так как они встроены и не увеличивают размер сборки.
  • При необходимости поддержки разных языков и сложных форматов лучше использовать специализированные библиотеки.
  • Форматирование лучше выполнять на уровне компонентов, чтобы данные в состоянии оставались в стандартном виде, а отображение происходило корректно и локализовано.
  • Реактивное обновление (например, часы или таймеры) реализуется через хуки useState и useEffect для минимизации лишних перерисовок.

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