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

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

Проблема

У дат нет универсального письменного формата. Последовательность 10/12/2025 означает 12 октября в США, но 10 декабря в Великобритании. Запись "Oct 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 и форматирует дату соответственно. Для en-US компонент покажет "October 12, 2025", а для en-GB — "12 October 2025".

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={`Article published on ${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 отобразит "Monday, October 12, 2025" для en-US и "Montag, 12. Oktober 2025" для de-DE. Компонент 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>Published: {formatLongDate(publishedDate)}</p>
      <div>{post.content}</div>
    </article>
  );
}

export const getStaticProps: GetStaticProps = async () => {
  const post = {
    title: "Understanding Internationalization",
    publishedAt: "2025-10-12T00:00:00Z",
    content: "Content here...",
  };

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

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