如何显示 AM/PM 或与语言环境相关的时间段
使用 JavaScript 显示符合各文化划分方式的时间段
介绍
当您显示像 4:00 这样的时间时,用户需要上下文来了解它是发生在早上还是下午。在英语中,您可以添加 AM 或 PM 来澄清。4:00 AM 发生在日出之前,而 4:00 PM 发生在下午。
其他语言并不仅仅翻译 AM 和 PM。许多文化将一天分为两个以上的时段,并为清晨、上午、下午、傍晚和夜晚等特定时段使用特定术语。西班牙语中有“madrugada”一词,用于表示午夜之后但黎明之前的时间。德语将一天分为六个不同的时段,而不是两个。一些语言将凌晨 1:00 称为“夜里 1 点”,而不是“早上 1 点”。
JavaScript 的 Intl.DateTimeFormat 提供了 dayPeriod 选项,可以自动显示这些特定文化的时间分段。本课程将解释日间时段在不同文化中的工作方式、它们为何对国际化应用程序很重要,以及如何使用适当的日间时段标签格式化时间。
为什么日间时段因文化而异
不同的文化发展出了不同的方式来将 24 小时的一天划分为命名的时段。这些划分反映了每种文化中人们对时间的思考和表达方式。
英语使用者将一天分为四个时段。早晨从午夜到中午,下午从中午到傍晚,傍晚从下午晚些时候到天黑,夜晚从天黑到午夜。AM 和 PM 提供了一个更简单的 12 小时制的两时段系统。
西班牙语使用者将“madrugada”视为一个独特的时段,涵盖午夜之后但人们通常尚未醒来的时间。这形成了一个五时段系统,区分了深夜时段和清晨时段。
俄语使用者使用“ночь”(夜晚)来指代人们通常在睡觉的任何时间。凌晨 1:00 被称为“夜里 1 点”,而不是“早上 1 点”,因为人们通常在这个时间睡觉。
德语将一天分为六个时段。“Morgen”(早晨)、“Vormittag”(上午)、“Mittag”(中午)、“Nachmittag”(下午)、“Abend”(傍晚)和“Nacht”(夜晚)各自涵盖特定的时间范围。
印尼语使用“pagi”(黎明到上午 10 点)、“siang”(上午 10 点到下午 2 点)、“sore”(下午 2 点到日落)和“malam”(夜晚)来根据太阳的位置将一天分为四个时段。
孟加拉语将一天分为六个时段。“ভোর”(黎明)、“সকাল”(早晨)、“দুপুর”(早午)、“বিকাল”(下午晚些时候)、“সন্ধ্যা”(傍晚)和“রাত”(夜晚)各自有特定的时间范围。
当您在国际化应用程序中显示时间时,您需要使用符合每种文化中用户自然谈论时间方式的术语。向所有用户显示“4 AM”忽略了其他语言如何描述该时间。
了解 dayPeriod 选项
Intl.DateTimeFormat 中的 dayPeriod 选项用于在格式化时间时包含特定于语言环境的时间段标识。除了显示小时和分钟外,格式化器还会在目标语言中添加适合该时间段的术语。
此选项仅适用于 12 小时制格式。在 24 小时制格式中,小时数字本身已经提供了足够的上下文。例如,04:00 明显是早晨,而 16:00 明显是下午,无需额外的标签。时间段的存在是为了消除 12 小时制中重复小时的歧义。
dayPeriod 选项接受三个值。narrow 生成最短的形式,通常是单个字母或缩写。short 生成缩写形式。long 生成完整的单词或短语。
对于许多语言环境,这三个值会生成相同的输出。Unicode 语言环境数据并未为每种语言环境和格式长度的组合定义不同的形式。当不存在不同形式时,无论指定哪个值,格式化器都会使用相同的输出。
使用时间段格式化时间
要显示时间段,请创建一个 Intl.DateTimeFormat 实例,并将 dayPeriod 选项设置为 narrow、short 或 long。您还必须包含一个时间组件选项(如 hour),并使用 hourCycle 指定 12 小时制格式。
const date = new Date('2025-01-15T04:30:00');
const formatter = new Intl.DateTimeFormat('en-US', {
hour: 'numeric',
minute: 'numeric',
hourCycle: 'h12',
dayPeriod: 'long'
});
console.log(formatter.format(date));
// 输出: "4:30 in the morning"
这将创建一个显示小时、分钟和时间段的格式化器。hourCycle: 'h12' 选项指定了 12 小时制格式,这是显示时间段所必需的。dayPeriod: 'long' 选项请求完整的时间段短语。
如果没有 dayPeriod 选项,格式化器将显示 "4:30 AM"。时间段选项用更具描述性的短语替代了简单的 AM/PM 指示符。
在不同时间显示时间段
时间段会根据被格式化的时间而变化。格式化器会根据语言环境的约定,自动为每个时间选择适当的时间段。
const options = {
hour: 'numeric',
minute: 'numeric',
hourCycle: 'h12',
dayPeriod: 'long'
};
const formatter = new Intl.DateTimeFormat('en-US', options);
const morning = new Date('2025-01-15T04:30:00');
console.log(formatter.format(morning));
// 输出: "4:30 in the morning"
const afternoon = new Date('2025-01-15T14:30:00');
console.log(formatter.format(afternoon));
// 输出: "2:30 in the afternoon"
const evening = new Date('2025-01-15T20:30:00');
console.log(formatter.format(evening));
// 输出: "8:30 in the evening"
const night = new Date('2025-01-15T23:30:00');
console.log(formatter.format(night));
// 输出: "11:30 at night"
英语区分早晨、下午、晚上和夜晚。每个时间段根据小时数会自动分配适当的短语。您无需手动确定适用的时间段,格式化器会根据 Unicode 语言环境数据自动处理。
比较窄格式、短格式和长格式
在某些语言环境中,这三种格式长度会产生不同的输出。差异因语言而异,可能微妙或不存在。
const date = new Date('2025-01-15T04:30:00');
const narrow = new Intl.DateTimeFormat('en-US', {
hour: 'numeric',
hourCycle: 'h12',
dayPeriod: 'narrow'
});
console.log(narrow.format(date));
// 输出: "4 in the morning"
const short = new Intl.DateTimeFormat('en-US', {
hour: 'numeric',
hourCycle: 'h12',
dayPeriod: 'short'
});
console.log(short.format(date));
// 输出: "4 in the morning"
const long = new Intl.DateTimeFormat('en-US', {
hour: 'numeric',
hourCycle: 'h12',
dayPeriod: 'long'
});
console.log(long.format(date));
// 输出: "4 in the morning"
对于美式英语,所有三种长度的输出是相同的。语言环境数据未为此语言和时间组合定义不同的形式。
某些语言环境确实区分长度。法语在窄格式和长格式之间会产生不同的输出。
const date = new Date('2025-01-15T04:30:00');
const frNarrow = new Intl.DateTimeFormat('fr-FR', {
hour: 'numeric',
hourCycle: 'h12',
dayPeriod: 'narrow'
});
console.log(frNarrow.format(date));
// 输出: "4 mat."
const frLong = new Intl.DateTimeFormat('fr-FR', {
hour: 'numeric',
hourCycle: 'h12',
dayPeriod: 'long'
});
console.log(frLong.format(date));
// 输出: "4 du matin"
法语使用 "mat." 作为缩写形式,使用 "du matin" 作为长形式。两者都表示早晨,但长形式更为明确。
除非您有特定的空间限制需要最短的输出,否则建议使用 long 格式以确保清晰度。较长的形式更易于用户理解,而且许多语言环境并未提供更短的替代形式。
不同语言环境中的时间段工作原理
不同的语言环境使用不同的时间段术语,并在不同的时间边界划分一天。格式化器会自动应用每个语言环境的约定。
const date = new Date('2025-01-15T04:30:00');
const options = {
hour: 'numeric',
hourCycle: 'h12',
dayPeriod: 'long'
};
const enUS = new Intl.DateTimeFormat('en-US', options);
console.log(enUS.format(date));
// 输出: "4 in the morning"
const enGB = new Intl.DateTimeFormat('en-GB', options);
console.log(enGB.format(date));
// 输出: "4 at night"
const deDK = new Intl.DateTimeFormat('de-DE', options);
console.log(deDK.format(date));
// 输出: "4 morgens"
const fr = new Intl.DateTimeFormat('fr-FR', options);
console.log(fr.format(date));
// 输出: "4 du matin"
英式英语将凌晨 4:30 视为“at night”而不是“in the morning”,这反映了不同文化对时间段的划分。德语使用“morgens”表示早晨时间。法语则使用“du matin”表示同一时间段。
这些差异并不是错误或不一致,而是反映了人们对时间的概念和表达方式的真实文化差异。格式化器会根据语言环境自动尊重这些差异。
时间段需要 12 小时制格式
dayPeriod 选项仅在您使用 hourCycle: 'h12' 或 hourCycle: 'h11' 指定 12 小时制格式时才有效。如果未使用 12 小时制格式,则不会显示时间段。
const date = new Date('2025-01-15T04:30:00');
const with12Hour = new Intl.DateTimeFormat('en-US', {
hour: 'numeric',
hourCycle: 'h12',
dayPeriod: 'long'
});
console.log(with12Hour.format(date));
// 输出: "4 in the morning"
const with24Hour = new Intl.DateTimeFormat('en-US', {
hour: 'numeric',
hourCycle: 'h23',
dayPeriod: 'long'
});
console.log(with24Hour.format(date));
// 输出: "04"
即使指定了该选项,24 小时制格式也不会显示时间段。在 24 小时制格式中,小时数字本身已经提供了足够的上下文,无需额外的标签。
h12 和 h11 的区别在于午夜和中午的编号方式。使用 h12 表示标准的 12 小时制时钟,小时从 1 到 12。使用 h11 表示 0 到 11 小时制系统。两者都可以与时间段一起使用。
将时间段与分钟和秒数结合
您可以将分钟和秒数与时间段一起包含。格式化器会根据语言环境的约定适当地定位时间段。
const date = new Date('2025-01-15T04:30:45');
const withMinutes = new Intl.DateTimeFormat('en-US', {
hour: 'numeric',
minute: 'numeric',
hourCycle: 'h12',
dayPeriod: 'long'
});
console.log(withMinutes.format(date));
// 输出: "4:30 in the morning"
const withSeconds = new Intl.DateTimeFormat('en-US', {
hour: 'numeric',
minute: 'numeric',
second: 'numeric',
hourCycle: 'h12',
dayPeriod: 'long'
});
console.log(withSeconds.format(date));
// 输出: "4:30:45 in the morning"
时间段出现在时间组件之后。您无需手动定位或格式化时间段。格式化器会根据语言环境的约定处理布局。
为用户的语言环境格式化带有时间段的时间
与硬编码特定语言环境不同,您可以使用浏览器中用户的首选语言。navigator.language 属性返回用户的首选语言。
const date = new Date('2025-01-15T04:30:00');
const formatter = new Intl.DateTimeFormat(navigator.language, {
hour: 'numeric',
minute: 'numeric',
hourCycle: 'h12',
dayPeriod: 'long'
});
console.log(formatter.format(date));
// 输出因用户的语言环境而异
// 对于 en-US: "4:30 in the morning"
// 对于 en-GB: "4:30 at night"
// 对于 de-DE: "4:30 morgens"
// 对于 fr-FR: "4:30 du matin"
这种方法显示的时间段与每个用户自然谈论时间的方式相匹配。浏览器提供语言偏好,Intl API 应用适当的时间段术语和边界。
何时使用时间段
当您希望提供比简单的 AM/PM 指示器更多的上下文时,时间段非常适用。它们使时间更具对话性,并且更容易一目了然地理解。
在用户界面中,时间出现在描述性文本旁边时使用时间段。例如,日历中显示 "4:30 in the morning" 比 "4:30 AM" 更清晰,因为该短语在连贯的文本中听起来更自然。
在通知和消息中使用时间段,其中对话语言可以提高可读性。例如,"您的会议将在晚上 8:30 开始" 比 "您的会议将在 8:30 PM 开始" 更易读。
在空间有限的紧凑显示中避免使用时间段。例如,表格、图表和密集布局中更适合使用标准的 AM/PM 指示器或 24 小时制。
在以 24 小时制显示时间时避免使用时间段。当小时数字已经指示一天中的时间时,时间段不会增加有用的信息。
摘要
Intl.DateTimeFormat 的 dayPeriod 选项用于显示与文化相关的时间段术语。不同的文化对一天的划分方式不同,例如西班牙语中的 "madrugada" 或德语中六个不同的时间段,而不仅仅是 AM 和 PM。
该选项接受三个值。narrow 生成最短的形式,short 生成缩写形式,long 生成完整的短语。许多语言环境对这三个值的输出是相同的。
时间段仅在使用 hourCycle: 'h12' 或 hourCycle: 'h11' 指定的 12 小时制时出现。在 24 小时制中不会出现时间段,因为小时数字已经提供了足够的上下文。
不同的语言环境使用不同的时间段术语,并在不同的时间点划分边界。格式化器会根据语言环境标识符自动应用这些约定。例如,英式英语将凌晨 4:30 视为 "at night",而美式英语将其视为 "in the morning"。