Как форматировать даты для разных локалей в TanStack Start v1

Отображение дат в региональных форматах

Проблема

У дат нет универсального формата отображения. Последовательность 10/12/2025 означает 12 октября в США, но 10 декабря в Великобритании. Запись "Oct 12, 2025" предполагает английские названия месяцев и определённый порядок. В каждом регионе свои ожидания по формату даты: порядок дня, месяца и года, выбор разделителей, написание или сокращение названий месяцев. Если приложение показывает даты только в одном фиксированном формате, это выглядит чуждо и сбивает с толку пользователей из большинства регионов.

Пользователи ожидают видеть даты в привычном для себя формате. То, что для одной аудитории выглядит естественно, для другой может быть непонятно или раздражающе. Без учёта локали форматирование дат становится источником неудобств, ухудшает пользовательский опыт и делает приложение менее профессиональным.

Решение

Форматируйте даты в зависимости от локали пользователя, преобразуя значения дат в строки, которые соответствуют региональным правилам порядка, разделителей и написания месяцев. React-intl предоставляет функции и компоненты для форматирования, которые используют встроенные в браузер API интернационализации и автоматически применяют нужные правила для каждой локали. Передавая значение даты и дополнительные параметры форматирования этим инструментам, приложение получает результат, который выглядит понятно и естественно для языка и региона пользователя.

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

Шаги

1. Создайте компонент, который форматирует даты с помощью хука useIntl

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

import { useIntl } from "react-intl";

export function EventDate({ date }: { date: Date }) {
  const intl = useIntl();

  return (
    <time dateTime={date.toISOString()}>
      {intl.formatDate(date, {
        year: "numeric",
        month: "long",
        day: "numeric",
      })}
    </time>
  );
}

Метод formatDate применяет правила отображения дат, характерные для локали. Объект options управляет тем, какие части даты будут показаны и насколько подробно. Отформатированная строка адаптируется к локали, которую предоставляет IntlProvider выше по дереву компонентов.

2. Форматируйте даты с определёнными стилями, используя предустановленные опции

Передавайте разные комбинации опций, чтобы управлять стилем формата даты, например, короткие числовые или длинные описательные даты.

import { useIntl } from "react-intl";

export function ArticleMetadata({ publishedAt }: { publishedAt: Date }) {
  const intl = useIntl();

  const shortDate = intl.formatDate(publishedAt, {
    year: "numeric",
    month: "short",
    day: "numeric",
  });

  const longDate = intl.formatDate(publishedAt, {
    year: "numeric",
    month: "long",
    day: "numeric",
    weekday: "long",
  });

  return (
    <div>
      <p>Published: {shortDate}</p>
      <p>Full date: {longDate}</p>
    </div>
  );
}

Опция month принимает значения, такие как numeric, 2-digit, short, long и narrow. Опция weekday добавляет день недели. Каждая локаль интерпретирует эти опции по-своему, чтобы результат соответствовал ожиданиям пользователя.

3. Используйте компонент FormattedDate для декларативного форматирования

Отображайте даты декларативно с помощью компонента FormattedDate, который принимает те же параметры форматирования, что и метод formatDate.

import { FormattedDate } from "react-intl";

export function OrderSummary({ orderDate }: { orderDate: Date }) {
  return (
    <div>
      <h2>Order placed on</h2>
      <FormattedDate
        value={orderDate}
        year="numeric"
        month="long"
        day="numeric"
      />
    </div>
  );
}

Компонент FormattedDate по умолчанию отображает отформатированную дату как React-фрагмент. Он использует локаль из контекста IntlProvider и применяет те же правила форматирования, что и императивный API. Такой подход отлично подходит, если в этой части дерева компонентов нужно показать только дату.

4. Форматируйте даты с указанием времени

Добавьте параметры часа и минуты, чтобы отображать дату и время в одной строке.

import { useIntl } from "react-intl";

export function AppointmentCard({ scheduledAt }: { scheduledAt: Date }) {
  const intl = useIntl();

  return (
    <div>
      <p>
        Scheduled for:{" "}
        {intl.formatDate(scheduledAt, {
          year: "numeric",
          month: "short",
          day: "numeric",
          hour: "numeric",
          minute: "2-digit",
        })}
      </p>
    </div>
  );
}

Добавление опций hour и minute позволяет получить строку с датой и временем вместе. Локаль определяет, использовать ли 12- или 24-часовой формат времени и как разделять дату и время. Это обеспечивает единообразие формата в соответствии с региональными стандартами отображения временных меток.