Next.js(Pages Router) v16에서 다양한 로케일에 맞게 날짜 포맷하는 방법

지역별 형식으로 날짜 표시하기

문제

날짜는 보편적인 표기 형식이 없습니다. 10/12/2025라는 순서는 미국에서는 10월 12일을 의미하지만 영국에서는 12월 10일을 의미합니다. "Oct 12, 2025"라고 쓰는 것은 영어 월 이름과 특정 순서 규칙을 가정합니다. 모든 지역에는 구성 요소의 순서, 구분 기호, 월 이름이 단어나 숫자로 표시되는지 여부를 포함하여 날짜 형식에 대한 고유한 기대치가 있습니다.

단일 형식으로 날짜를 표시하면 해당 형식 지역 외부의 사용자에게 애플리케이션이 이질적으로 느껴집니다. 사용자는 날짜를 잘못 해석하거나 읽기 어려울 수 있습니다. 한 사용자 그룹에게 명확한 날짜가 다른 그룹에게는 혼란스럽거나 모호할 수 있습니다.

해결책

사용자의 로케일을 기반으로 날짜 값을 순서, 구분 기호 및 월 이름에 대한 지역 규칙을 따르는 문자열로 변환하여 날짜를 형식화합니다. 브라우저의 Intl.DateTimeFormat API는 로케일과 선택적 형식 지정 기본 설정이 주어지면 로케일별 형식 지정 규칙을 자동으로 처리합니다.

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. 표준 옵션으로 형식 세부 정보 조정하기

"numeric", "2-digit", "long", "short" 또는 "narrow"와 같은 값을 가진 year, month, day, weekday와 같은 옵션을 지정하여 날짜 구성 요소의 표현을 제어할 수 있습니다.

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 컴포넌트는 en-US에서 "Monday, October 12, 2025"로, de-DE에서 "Montag, 12. Oktober 2025"로 렌더링됩니다. 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 },
  };
};

이 페이지는 사용자의 로케일 형식으로 발행 날짜를 표시하여 모든 지역의 독자들이 날짜를 즉시 명확하고 친숙하게 이해할 수 있도록 합니다.