Как форматировать даты для разных локалей в Next.js (Pages Router) v16

Отображение дат в форматах, специфичных для региона

Проблема

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

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

Решение

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

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

Шаги

1. Создайте компонент для форматирования даты с использованием FormattedDate

Компонент FormattedDate принимает значение даты и параметры форматирования, соответствующие Intl.DateTimeFormatOptions. Создайте компонент, который отображает дату с нужным уровнем детализации.

import { FormattedDate } from "react-intl";

interface EventDateProps {
  date: Date;
}

export function EventDate({ date }: EventDateProps) {
  return (
    <time dateTime={date.toISOString()}>
      <FormattedDate value={date} year="numeric" month="long" day="numeric" />
    </time>
  );
}

FormattedDate считывает локаль из контекста IntlProvider и форматирует дату соответствующим образом. Компонент отобразит "12 октября 2025" для ru-RU и "October 12, 2025" для en-US.

2. Императивное форматирование дат с помощью useIntl

В случаях, когда нельзя использовать React-компонент, например, при установке текстовых атрибутов, используйте хук useIntl для доступа к методу formatDate.

import { useIntl } from "react-intl";

interface ArticleImageProps {
  src: string;
  publishedAt: Date;
}

export function ArticleImage({ src, publishedAt }: ArticleImageProps) {
  const intl = useIntl();

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

  return <img src={src} alt={`Статья опубликована ${formattedDate}`} />;
}

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

3. Настройка деталей форматирования с помощью стандартных опций

Управляйте отображением компонентов даты, указывая такие параметры, как year, month, day и weekday, с возможными значениями "numeric", "2-digit", "long", "short" или "narrow".

import { FormattedDate } from "react-intl";

export function FullEventDate({ date }: { date: Date }) {
  return (
    <FormattedDate
      value={date}
      weekday="long"
      year="numeric"
      month="long"
      day="numeric"
    />
  );
}

export function CompactDate({ date }: { date: Date }) {
  return (
    <FormattedDate value={date} year="2-digit" month="2-digit" day="2-digit" />
  );
}

Компонент FullEventDate отобразит "понедельник, 12 октября 2025 года" на ru-RU и "Monday, October 12, 2025" на en-US. Компонент CompactDate создаёт более короткие числовые форматы, подходящие для таблиц или ограниченных пространств.

4. Создание вспомогательной функции для форматирования дат

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

import { useIntl } from "react-intl";

export function useDateFormatters() {
  const intl = useIntl();

  return {
    formatShortDate: (date: Date) =>
      intl.formatDate(date, {
        year: "numeric",
        month: "short",
        day: "numeric",
      }),

    formatLongDate: (date: Date) =>
      intl.formatDate(date, {
        weekday: "long",
        year: "numeric",
        month: "long",
        day: "numeric",
      }),

    formatMonthYear: (date: Date) =>
      intl.formatDate(date, {
        year: "numeric",
        month: "long",
      }),
  };
}

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

5. Использование хелпера в компоненте страницы

Примените хелпер форматирования даты на странице Next.js, чтобы отображать даты, учитывающие локаль пользователя.

import { GetStaticProps } from "next";
import { useDateFormatters } from "../lib/useDateFormatters";

interface Post {
  title: string;
  publishedAt: string;
  content: string;
}

interface BlogPostPageProps {
  post: Post;
}

export default function BlogPostPage({ post }: BlogPostPageProps) {
  const { formatLongDate } = useDateFormatters();
  const publishedDate = new Date(post.publishedAt);

  return (
    <article>
      <h1>{post.title}</h1>
      <p>Опубликовано: {formatLongDate(publishedDate)}</p>
      <div>{post.content}</div>
    </article>
  );
}

export const getStaticProps: GetStaticProps = async () => {
  const post = {
    title: "Понимание интернационализации",
    publishedAt: "2025-10-12T00:00:00Z",
    content: "Содержимое здесь...",
  };

  return {
    props: { post },
  };
};

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