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. 標準オプションでフォーマットの詳細度を調整する
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コンポーネントは、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 },
};
};
ページは、ユーザーのロケール形式で公開日を表示し、どの地域の読者にとっても日付が即座に明確で親しみやすいものになります。