如何在 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 选项可接受 numeric、2-digit、short、long 和 narrow 等值。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>
);
}
添加 hour 和 minute 选项后,将生成包含日期和时间的组合字符串。所用语言区域会决定采用 12 小时制还是 24 小时制,以及日期和时间的分隔方式,从而确保时间戳的显示格式符合本地习惯。