如何显示时区名称,如 PST 或 Pacific Standard Time

使用 JavaScript 以缩写、全称或偏移量格式显示时区名称

简介

当你向用户显示时间时,标明时区有助于他们判断该时间是本地时区还是其他时区。例如,安排在 3:00 PM PST 的会议会让用户知道需要从太平洋时间进行换算。如果没有 PST 标签,用户就需要猜测适用的是哪个时区。

时区可以有多种显示格式。你可以显示像 PST 这样的缩写名、像 Pacific Standard Time 这样的全称,或像 GMT-8 这样的偏移量格式。不同的格式适用于不同场景。缩写节省空间但可能有歧义,全称清晰但占用空间较大,偏移量适用于只关心时差而非具体时区名称的场景。

JavaScript 提供了 Intl.DateTimeFormat API,可自动显示时区名称。本教程将介绍时区名称的概念、标准时间与夏令时的切换,以及如何以不同格式显示时区名称。

理解时区名称格式

时区名称有几种不同的格式,每种格式都有其特点。

短名称使用缩写,如 PSTESTJST。这种方式节省空间,但可能存在歧义。例如 CST 既可能指北美中部标准时间,也可能指中国标准时间或古巴标准时间。

长名称则完整拼写时区名称,如 Pacific Standard TimeEastern Standard TimeJapan Standard Time。这种方式避免歧义,但占用空间较大。

通用名称指的是时区本身,并未具体说明当前是标准时间还是夏令时。PT 表示太平洋时间,具体是 PST 还是 PDT 取决于日期。

偏移格式显示与 UTC 的小时差。GMT-8 表示比格林威治标准时间晚 8 小时。GMT-05:00 表示晚 5 小时,小时和分钟之间用冒号分隔。

选择哪种格式取决于你的使用场景。当空间有限且允许一定歧义时,使用短名称。当清晰度比空间更重要时,使用长名称。需要显示与 UTC 的数值关系时,使用偏移量。

使用 Intl.DateTimeFormat 显示时区名称

Intl.DateTimeFormat 构造函数接受一个 timeZoneName 选项,用于控制格式化日期和时间时时区名称的显示方式。

const formatter = new Intl.DateTimeFormat('en-US', {
  timeZone: 'America/Los_Angeles',
  timeZoneName: 'short',
  year: 'numeric',
  month: 'numeric',
  day: 'numeric',
  hour: 'numeric',
  minute: 'numeric'
});

const date = new Date('2025-01-15T15:30:00Z');
console.log(formatter.format(date));
// Output: "1/15/2025, 7:30 AM PST"

这会创建一个用于美式英语的格式化器,显示 America/Los_Angeles 时区的时间。timeZoneName: 'short' 选项会在输出中添加缩写的时区名称。结果会在末尾包含 PST

timeZone 选项设置格式化时使用的时区。timeZoneName 选项控制是否以及如何显示时区名称。这两个选项配合使用。timeZone 决定时间转换,而 timeZoneName 决定标签显示。

显示时区缩写名称

timeZoneName: 'short' 选项用于显示时区名称的缩写形式。

const formatter = new Intl.DateTimeFormat('en-US', {
  timeZone: 'America/New_York',
  timeZoneName: 'short',
  year: 'numeric',
  month: 'numeric',
  day: 'numeric',
  hour: 'numeric',
  minute: 'numeric'
});

const date = new Date('2025-01-15T15:30:00Z');
console.log(formatter.format(date));
// Output: "1/15/2025, 10:30 AM EST"

短格式会为东部标准时间生成 EST。该格式紧凑,适用于表格、列表或其他空间受限的布局。

不同时区会生成不同的缩写。

const date = new Date('2025-01-15T15:30:00Z');

const formatters = [
  { timeZone: 'America/Los_Angeles', name: 'Pacific' },
  { timeZone: 'America/Chicago', name: 'Central' },
  { timeZone: 'America/New_York', name: 'Eastern' },
  { timeZone: 'Europe/London', name: 'London' },
  { timeZone: 'Asia/Tokyo', name: 'Tokyo' }
];

formatters.forEach(({ timeZone, name }) => {
  const formatter = new Intl.DateTimeFormat('en-US', {
    timeZone: timeZone,
    timeZoneName: 'short',
    hour: 'numeric',
    minute: 'numeric'
  });
  console.log(`${name}: ${formatter.format(date)}`);
});
// Output:
// Pacific: 7:30 AM PST
// Central: 9:30 AM CST
// Eastern: 10:30 AM EST
// London: 3:30 PM GMT
// Tokyo: 12:30 AM JST

每个时区都有其标准缩写。太平洋时区用 PST,中部时区用 CST,东部时区用 EST,伦敦用 GMT,东京用 JST

显示时区全名

timeZoneName: 'long' 选项会显示完整的时区名称。

const formatter = new Intl.DateTimeFormat('en-US', {
  timeZone: 'America/Los_Angeles',
  timeZoneName: 'long',
  year: 'numeric',
  month: 'numeric',
  day: 'numeric',
  hour: 'numeric',
  minute: 'numeric'
});

const date = new Date('2025-01-15T15:30:00Z');
console.log(formatter.format(date));
// Output: "1/15/2025, 7:30 AM Pacific Standard Time"

长格式会生成 Pacific Standard Time,而不是 PST。这样可以消除歧义,但会占用更多空间。

当需要清晰表达且空间充足时,长名称非常适用。

const date = new Date('2025-01-15T15:30:00Z');

const formatter = new Intl.DateTimeFormat('en-US', {
  timeZone: 'America/New_York',
  timeZoneName: 'long',
  hour: 'numeric',
  minute: 'numeric'
});

console.log(formatter.format(date));
// Output: "10:30 AM Eastern Standard Time"

全名可以让用户无需解读缩写就能明确对应的时区。

显示时区偏移量

timeZoneName: 'shortOffset' 选项会以紧凑格式显示 UTC 偏移量。

const formatter = new Intl.DateTimeFormat('en-US', {
  timeZone: 'America/Los_Angeles',
  timeZoneName: 'shortOffset',
  hour: 'numeric',
  minute: 'numeric'
});

const date = new Date('2025-01-15T15:30:00Z');
console.log(formatter.format(date));
// Output: "7:30 AM GMT-8"

此格式会显示 GMT-8,表示该时区比 UTC 晚 8 小时。当具体时区名称不如与 UTC 的数值关系重要时,偏移量格式非常适用。

timeZoneName: 'longOffset' 选项会以小时和分钟显示偏移量。

const formatter = new Intl.DateTimeFormat('en-US', {
  timeZone: 'America/Los_Angeles',
  timeZoneName: 'longOffset',
  hour: 'numeric',
  minute: 'numeric'
});

const date = new Date('2025-01-15T15:30:00Z');
console.log(formatter.format(date));
// Output: "7:30 AM GMT-08:00"

此格式会显示 GMT-08:00,小时和分钟之间用冒号分隔。该格式更为精确,并遵循 ISO 8601 标准。

具有半小时或 45 分钟偏移量的时区会在长格式下显示完整偏移量。

const formatter = new Intl.DateTimeFormat('en-US', {
  timeZone: 'Asia/Kolkata',
  timeZoneName: 'longOffset',
  hour: 'numeric',
  minute: 'numeric'
});

const date = new Date('2025-01-15T15:30:00Z');
console.log(formatter.format(date));
// Output: "9:00 PM GMT+05:30"

印度标准时间比 UTC 快 5 小时 30 分钟。长偏移量格式会显示为 GMT+05:30

显示通用时区名称

timeZoneName: 'shortGeneric' 选项会显示一个通用缩写,无论是否处于夏令时都适用。

const winterFormatter = new Intl.DateTimeFormat('en-US', {
  timeZone: 'America/Los_Angeles',
  timeZoneName: 'shortGeneric',
  hour: 'numeric',
  minute: 'numeric'
});

const summerFormatter = new Intl.DateTimeFormat('en-US', {
  timeZone: 'America/Los_Angeles',
  timeZoneName: 'shortGeneric',
  hour: 'numeric',
  minute: 'numeric'
});

const winterDate = new Date('2025-01-15T15:30:00Z');
const summerDate = new Date('2025-07-15T15:30:00Z');

console.log(winterFormatter.format(winterDate));
// Output: "7:30 AM PT"

console.log(summerFormatter.format(summerDate));
// Output: "8:30 AM PT"

冬季和夏季日期下,太平洋时间均显示为 PT 。通用格式不会区分太平洋标准时间和太平洋夏令时间。当你需要一个不随季节变化的统一标签时,这种方式非常适用。

timeZoneName: 'longGeneric' 选项会提供完整的通用名称。

const formatter = new Intl.DateTimeFormat('en-US', {
  timeZone: 'America/Los_Angeles',
  timeZoneName: 'longGeneric',
  hour: 'numeric',
  minute: 'numeric'
});

const date = new Date('2025-01-15T15:30:00Z');
console.log(formatter.format(date));
// Output: "7:30 AM Pacific Time"

这会显示 Pacific Time ,而不是 Pacific Standard Time 。通用长格式可以清晰表达时区信息,而无需区分标准时间或夏令时。

夏令时如何影响时区名称

时区名称会在标准时间和夏令时之间切换。timeZoneName 选项会自动反映这种变化。

const formatter = new Intl.DateTimeFormat('en-US', {
  timeZone: 'America/Los_Angeles',
  timeZoneName: 'short',
  hour: 'numeric',
  minute: 'numeric'
});

const winterDate = new Date('2025-01-15T15:30:00Z');
const summerDate = new Date('2025-07-15T15:30:00Z');

console.log(formatter.format(winterDate));
// Output: "7:30 AM PST"

console.log(formatter.format(summerDate));
// Output: "8:30 AM PDT"

一月时,格式化器会显示 PST (太平洋标准时间);七月时,会显示 PDT (太平洋夏令时间)。格式化器会根据日期自动选择正确的名称。

偏移量也会在标准时间和夏令时之间变化。

const formatter = new Intl.DateTimeFormat('en-US', {
  timeZone: 'America/Los_Angeles',
  timeZoneName: 'shortOffset',
  hour: 'numeric',
  minute: 'numeric'
});

const winterDate = new Date('2025-01-15T15:30:00Z');
const summerDate = new Date('2025-07-15T15:30:00Z');

console.log(formatter.format(winterDate));
// Output: "7:30 AM GMT-8"

console.log(formatter.format(summerDate));
// Output: "8:30 AM GMT-7"

冬季时,太平洋时间为 GMT-8 ;夏季时为 GMT-7 。夏令时开始时,偏移量会增加一小时。

长名称同样会反映这种变化。

const formatter = new Intl.DateTimeFormat('en-US', {
  timeZone: 'America/Los_Angeles',
  timeZoneName: 'long',
  hour: 'numeric',
  minute: 'numeric'
});

const winterDate = new Date('2025-01-15T15:30:00Z');
const summerDate = new Date('2025-07-15T15:30:00Z');

console.log(formatter.format(winterDate));
// Output: "7:30 AM Pacific Standard Time"

console.log(formatter.format(summerDate));
// Output: "8:30 AM Pacific Daylight Time"

长格式会从 Pacific Standard Time 变为 Pacific Daylight Time 。格式化器会根据日期和时区自动处理这些切换。

在不同语言中显示时区名称

时区名称在不同语言中会有所不同。区域标识符决定了格式化程序使用哪种语言来显示时区名称。

const date = new Date('2025-01-15T15:30:00Z');

const enFormatter = new Intl.DateTimeFormat('en-US', {
  timeZone: 'America/Los_Angeles',
  timeZoneName: 'long',
  hour: 'numeric',
  minute: 'numeric'
});

const esFormatter = new Intl.DateTimeFormat('es-ES', {
  timeZone: 'America/Los_Angeles',
  timeZoneName: 'long',
  hour: 'numeric',
  minute: 'numeric'
});

const frFormatter = new Intl.DateTimeFormat('fr-FR', {
  timeZone: 'America/Los_Angeles',
  timeZoneName: 'long',
  hour: 'numeric',
  minute: 'numeric'
});

console.log(enFormatter.format(date));
// Output: "7:30 AM Pacific Standard Time"

console.log(esFormatter.format(date));
// Output: "7:30 hora estándar del Pacífico"

console.log(frFormatter.format(date));
// Output: "07:30 heure normale du Pacifique"

英文显示 Pacific Standard Time,西班牙语显示 hora estándar del Pacífico,法语显示 heure normale du Pacifique。每种语言都使用自己的时区名称翻译。

缩写形式通常在不同语言中保持一致,因为它们是缩写。

const date = new Date('2025-01-15T15:30:00Z');

const enFormatter = new Intl.DateTimeFormat('en-US', {
  timeZone: 'America/Los_Angeles',
  timeZoneName: 'short',
  hour: 'numeric',
  minute: 'numeric'
});

const esFormatter = new Intl.DateTimeFormat('es-ES', {
  timeZone: 'America/Los_Angeles',
  timeZoneName: 'short',
  hour: 'numeric',
  minute: 'numeric'
});

console.log(enFormatter.format(date));
// Output: "7:30 AM PST"

console.log(esFormatter.format(date));
// Output: "7:30 PST"

英文和西班牙语都使用 PST 作为缩写。但在本例中,西班牙语省略了 AM 指示符,因为西班牙语的格式习惯与英语不同。

偏移量在所有语言中都保持为数字。

const date = new Date('2025-01-15T15:30:00Z');

const enFormatter = new Intl.DateTimeFormat('en-US', {
  timeZone: 'America/Los_Angeles',
  timeZoneName: 'longOffset',
  hour: 'numeric',
  minute: 'numeric'
});

const jaFormatter = new Intl.DateTimeFormat('ja-JP', {
  timeZone: 'America/Los_Angeles',
  timeZoneName: 'longOffset',
  hour: 'numeric',
  minute: 'numeric'
});

console.log(enFormatter.format(date));
// Output: "7:30 AM GMT-08:00"

console.log(jaFormatter.format(date));
// Output: "7:30 GMT-08:00"

英文和日文都显示 GMT-08:00 作为偏移量。数字偏移量无需翻译。

仅显示时区名称

可以通过省略其他日期和时间组件,仅显示时区名称。

const formatter = new Intl.DateTimeFormat('en-US', {
  timeZone: 'America/Los_Angeles',
  timeZoneName: 'long'
});

const date = new Date('2025-01-15T15:30:00Z');
console.log(formatter.format(date));
// Output: "Pacific Standard Time"

当只指定 timeZoneName 而不包含其他选项时,格式化程序只输出时区名称。当需要将时区与日期和时间分开显示时,这种方式非常实用。

你可以用它来创建标签或图例。

const timeZones = [
  'America/Los_Angeles',
  'America/Chicago',
  'America/New_York',
  'Europe/London',
  'Asia/Tokyo'
];

const formatter = new Intl.DateTimeFormat('en-US', {
  timeZoneName: 'long'
});

const date = new Date();

timeZones.forEach(timeZone => {
  formatter = new Intl.DateTimeFormat('en-US', {
    timeZone: timeZone,
    timeZoneName: 'long'
  });
  console.log(formatter.format(date));
});
// Output:
// Pacific Standard Time (or Pacific Daylight Time depending on date)
// Central Standard Time (or Central Daylight Time depending on date)
// Eastern Standard Time (or Eastern Daylight Time depending on date)
// Greenwich Mean Time (or British Summer Time depending on date)
// Japan Standard Time

这会生成一个适合在下拉菜单或选择界面中显示的时区名称列表。

将时区名称与特定日期格式结合显示

你可以将时区名称与特定的日期和时间格式选项结合使用。

const formatter = new Intl.DateTimeFormat('en-US', {
  timeZone: 'America/New_York',
  timeZoneName: 'short',
  weekday: 'long',
  year: 'numeric',
  month: 'long',
  day: 'numeric',
  hour: 'numeric',
  minute: 'numeric'
});

const date = new Date('2025-01-15T15:30:00Z');
console.log(formatter.format(date));
// Output: "Wednesday, January 15, 2025, 10:30 AM EST"

这会将完整日期格式与时区缩写结合。输出内容包括星期、完整月份名称、日期、年份、时间和时区缩写。

你可以使用此方法来创建完整的日期时间显示。

const formatter = new Intl.DateTimeFormat('en-US', {
  timeZone: 'America/Los_Angeles',
  timeZoneName: 'long',
  dateStyle: 'full',
  timeStyle: 'long'
});

const date = new Date('2025-01-15T15:30:00Z');
console.log(formatter.format(date));
// Output: "Wednesday, January 15, 2025 at 7:30:00 AM Pacific Standard Time"

请注意,timeZoneName 选项不能与 dateStyletimeStyle 一起使用。如果你需要使用样式快捷方式,时区名称已经包含在 longfull 时间样式中。

const formatter = new Intl.DateTimeFormat('en-US', {
  timeZone: 'America/Los_Angeles',
  dateStyle: 'full',
  timeStyle: 'long'
});

const date = new Date('2025-01-15T15:30:00Z');
console.log(formatter.format(date));
// Output: "Wednesday, January 15, 2025 at 7:30:00 AM PST"

long 时间样式会自动包含简短的时区名称,无需单独指定 timeZoneName

为活动日程显示时区名称

时区名称有助于用户了解不同地区的活动时间。

const formatter = new Intl.DateTimeFormat('en-US', {
  timeZoneName: 'short',
  month: 'short',
  day: 'numeric',
  hour: 'numeric',
  minute: 'numeric'
});

const events = [
  { name: 'Kickoff Meeting', time: '2025-03-15T14:00:00Z', timeZone: 'America/New_York' },
  { name: 'Design Review', time: '2025-03-15T17:00:00Z', timeZone: 'America/Los_Angeles' },
  { name: 'Sprint Planning', time: '2025-03-16T01:00:00Z', timeZone: 'Asia/Tokyo' }
];

events.forEach(event => {
  const localFormatter = new Intl.DateTimeFormat('en-US', {
    timeZone: event.timeZone,
    timeZoneName: 'short',
    month: 'short',
    day: 'numeric',
    hour: 'numeric',
    minute: 'numeric'
  });

  const date = new Date(event.time);
  console.log(`${event.name}: ${localFormatter.format(date)}`);
});
// Output:
// Kickoff Meeting: Mar 15, 9:00 AM EST
// Design Review: Mar 15, 9:00 AM PST
// Sprint Planning: Mar 16, 10:00 AM JST

每个活动都会显示其本地时区。用户可以看到 Kickoff Meeting 在东部时间上午 9:00,Design Review 在太平洋时间上午 9:00,Sprint Planning 在日本时间上午 10:00。

你也可以将同一个活动显示在多个时区。

const meetingTime = new Date('2025-03-15T17:00:00Z');

const timeZones = [
  { zone: 'America/Los_Angeles', label: 'Pacific' },
  { zone: 'America/Chicago', label: 'Central' },
  { zone: 'America/New_York', label: 'Eastern' },
  { zone: 'Europe/London', label: 'London' }
];

console.log('Global Team Meeting:');
timeZones.forEach(({ zone, label }) => {
  const formatter = new Intl.DateTimeFormat('en-US', {
    timeZone: zone,
    timeZoneName: 'short',
    hour: 'numeric',
    minute: 'numeric'
  });
  console.log(`${label}: ${formatter.format(meetingTime)}`);
});
// Output:
// Global Team Meeting:
// Pacific: 9:00 AM PST
// Central: 11:00 AM CST
// Eastern: 12:00 PM EST
// London: 5:00 PM GMT

这会将一次会议时间转换为多个时区,来自不同地区的团队成员可以快速找到他们的本地时间。