如何在 TanStack Start v1 中为不同地区格式化日期

以地区特定的格式显示日期

问题

日期没有统一的显示格式。例如,10/12/2025 在美国表示 10 月 12 日,而在英国则表示 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 提供的 locale 自动适配。

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 选项可接受 numeric2-digitshortlongnarrow 等值。weekday 选项可添加星期几。每个 locale 会根据自身规范解释这些选项,确保输出符合用户预期。

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 fragment 的形式渲染格式化日期。它会使用 IntlProvider context 中的 locale,并应用与命令式 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>
  );
}

添加 hourminute 选项后,将生成包含日期和时间的组合字符串。所用语言区域会决定采用 12 小时制还是 24 小时制,以及日期和时间的分隔方式,从而确保时间戳的显示格式符合本地习惯。