日期和时间格式化
想看视频吗?
日期和时间的格式在不同地区差异很大(例如,en-US 中是 “Apr 24, 2023”,而 uk-UA 中是 “24 квіт. 2023 р.”)。通过使用 next-intl 的格式化功能,您可以在 Next.js 应用中自动处理国际化差异。
格式化日期和时间
您可以使用从 useFormatter 钩子返回的 dateTime 函数格式化不属于消息的纯日期:
import {useFormatter} from 'next-intl';
function Component() {
const format = useFormatter();
const dateTime = new Date('2020-11-20T10:36:01.516Z');
// 渲染结果为 "Nov 20, 2020"
format.dateTime(dateTime, {
year: 'numeric',
month: 'short',
day: 'numeric'
});
// 渲染结果为 "11:36 AM"
format.dateTime(dateTime, {hour: 'numeric', minute: 'numeric'});
}查看 MDN 上关于 DateTimeFormat 的文档了解可以传递给 dateTime 函数的更多选项,或者尝试 交互式探索器 来体验 Intl.DateTimeFormat。
如果您配置了全局格式,可以通过将名称作为第二个参数传递来引用它们:
// 使用全局格式
format.dateTime(dateTime, 'short');
// 可选覆盖部分选项
format.dateTime(dateTime, 'short', {year: 'numeric'});格式化相对时间
您可以使用 relativeTime 函数格式化不属于消息的纯日期:
import {useFormatter} from 'next-intl';
function Component() {
const format = useFormatter();
const dateTime = new Date('2020-11-20T08:30:00.000Z');
// 一个参考时间点
const now = new Date('2020-11-20T10:36:00.000Z');
// 这将渲染为 "2 hours ago"
format.relativeTime(dateTime, now);
}注意,数值会被四舍五入,例如经过 126 分钟,会返回 “2 hours ago”。
更多学习:
useNow 钩子
由于传入 now 是常见模式,next-intl 提供了一个便捷钩子来获取当前日期时间:
import {useNow, useFormatter} from 'next-intl';
function FormattedDate({date}) {
const now = useNow();
const format = useFormatter();
format.relativeTime(date, now);
}与在组件中直接调用 new Date() 相比,useNow 有以下优势:
- 在客户端重新渲染时返回的值一致。
- 可以可选使用
updateInterval持续更新数值。 - 数值可以可选从全局值初始化。默认情况下,
useNow会使用当前时间。
updateInterval 参数
如果希望相对时间随时间更新,可以使用 useNow 钩子实现:
import {useNow, useFormatter} from 'next-intl';
function Component() {
// 初始使用全局的 now 值 …
const now = useNow({
// … 并且每 10 秒更新一次
updateInterval: 1000 * 10
});
const format = useFormatter();
const dateTime = new Date('2020-11-20T10:36:01.516Z');
// 渲染例如 "2 hours ago" 并持续更新
format.relativeTime(dateTime, now);
}自定义单位
默认情况下,relativeTime 会基于传入的日期和 now 之间的差异自动选择单位,比如 “3 seconds” 或者 “5 days”。
如果想使用特定单位,可以通过第二个参数传递选项:
import {useFormatter} from 'next-intl';
function Component() {
const format = useFormatter();
const dateTime = new Date('2020-03-20T08:30:00.000Z');
const now = new Date('2020-11-22T10:36:00.000Z');
// 渲染 "247 days ago"
format.relativeTime(dateTime, {now, unit: 'day'});
}格式化日期和时间范围
您可以使用 dateTimeRange 函数格式化日期和时间区间:
import {useFormatter} from 'next-intl';
function Component() {
const format = useFormatter();
const dateTimeA = new Date('2020-11-20T08:30:00.000Z');
const dateTimeB = new Date('2021-01-24T08:30:00.000Z');
// 渲染 "Nov 20, 2020 – Jan 24, 2021"
format.dateTimeRange(dateTimeA, dateTimeB, {
year: 'numeric',
month: 'short',
day: 'numeric'
});
}如果您配置了全局格式,可以通过第三个参数传入格式名称来引用它们:
// 使用全局格式
format.dateTimeRange(dateTimeA, dateTimeB, 'short');
// 可选覆盖部分选项
format.dateTimeRange(dateTimeA, dateTimeB, 'short', {year: 'numeric'});消息中的日期和时间
日期和时间可以通过 ICU 语法嵌入消息中。
{
"ordered": "Ordered on {orderDate, date, medium}"
}默认支持的格式包括:full、long、medium 和 short。
如果您与翻译人员合作,使用支持 ICU 日期时间语法的编辑器会非常有帮助(例如 Crowdin 编辑器)。
您也可以使用日期骨架自定义格式:
{
// 渲染例如 "Ordered on Jul 9, 2024"
"ordered": "Ordered on {orderDate, date, ::yyyyMMMd}"
}注意前导的 :: 表示应使用骨架格式。
支持的 ICU 格式如下:
| 符号 | 含义 | 模式 | 示例 |
|---|---|---|---|
| G | 纪元设计ator(包含日期) | G GGGG GGGGG | 7/9/2024 AD 7/9/2024 Anno Domini 7/9/2024 A |
| y | 年 | y yy yyyy | 2024 24 2024 |
| M | 月份(年内) | M MM MMM MMMM MMMMM | 7 07 Jul July J |
| d | 月内日期 | d dd | 9 09 |
| E | 星期几 | E EEEE EEEEE | Tue Tuesday T |
| h | 小时(1-12) | h hh | 9 AM 09 AM |
| K | 小时(0-11) | K KK | 0 AM (12 AM 使用 h)00 AM |
| H | 小时(0-23) | HH | 09 |
| k | 小时(1-24) | kk | 24(使用 H 时为 00) |
| m | 分钟(如果包含秒数则为两位) | m mmss | 6 06:03 |
| s | 秒数(如果包含分钟则为两位) | s mmss | 3 06:03 |
| z | 时区 | z zzzz | GMT+2 Central European Summer Time |
模式可以互相组合,例如 yyyyMMMd 会输出 “Jul 9, 2024”。
自定义日期和时间格式
想在消息中使用自定义格式,可以基于 DateTimeFormat 选项 提供格式化器并通过名称引用。
{
"ordered": "Ordered on {orderDate, date, short}"
}t(
'ordered',
{orderDate: new Date('2020-11-20T10:36:01.516Z')},
{
dateTime: {
short: {
day: 'numeric',
month: 'short',
year: 'numeric'
}
}
}
);若要在多个组件间复用日期和时间格式,可以配置 全局格式。