JavaScript 中的时间本地化

Avatar of Chris Coyier
Chris Coyier

DigitalOcean 为您旅程的每个阶段提供云产品。立即开始使用 200 美元的免费额度!

假设您有一个想要在网站上显示的时间。您已在您的时区中输入了它。您始终可以明确说明,例如:下午 3:00 东部标准时间。然后让读者将其转换为他们当地时间。每个时区 是一个非常好的网站。

但为读者本地化时间会更好。时区转换非常混乱。而且这是计算机擅长的领域。毕竟,JavaScript 知道读者所在的时区。

我相信有很多方法可以做到这一点。我最近在一个新项目中需要这样做,我借鉴了 Dave Rupert 的做法,他在ShopTalk 的网站上实现了它,以显示我们下次直播的本地化时间。

Moment.jsMoment Timezone 可以完成这项工作。如果您需要进行任何其他更复杂日期和时间操作或相对计算(例如“32 分钟前”、“2015 年 8 月 12 日”),那么使用这些库会非常方便。

我们还需要检测时区本身,值得庆幸的是,有一个库可以做到这一点

所以我们将使用

  • jstz.js
  • moment.js
  • moment-timezone.js

您可以通过任何方式打包或链接这些库。

步骤 1:获取时区

在获取时区后,不妨将其存储在 localStorage 中。这样可以减少浏览器下次检索时所需的工作量。

if (!sessionStorage.getItem('timezone')) {
  var tz = jstz.determine() || 'UTC';
  sessionStorage.setItem('timezone', tz.name());
}
var currTz = sessionStorage.getItem('timezone');

步骤 2:获取时间值

Moment 期望一个日期/时间值(以UTC 格式表示),例如

2015-08-12T14:30Z

如果我们只对时间感兴趣,我们可以从 Moment 本身创建该字符串的日期部分,表示今天的日期(这使得格式化更容易)。日期实际上很重要,因为 UGHGKGJHGH 夏令时。

var date = moment().format("YYYY-MM-DD");

然后我们将创建最终字符串,假设我们有一个包含我们想要的时间的变量

var stamp = date + "T" + theTime + "Z";

并将其转换为 Moment 对象

var momentTime = moment(stamp);

步骤 3:本地化时间

现在我们可以使用 Moment Timezone 调整/本地化该时间

var tzTime = momentTime.tz(currTz);

并正确格式化以供显示

var formattedTime = tzTime.format('h:mm A');

步骤 4:使用它

现在我们可以在页面上的任何位置放置它。如果您也输出时区,您甚至可以替换页面上当前输出的时间,因为即使时区检测失败,它也会回退到 UTC 并将其输出为时区。

output.textContent = "Time in " + currTz + ": " + formattedTime;

调整时间

有时这样做是有意义的(可能从 CMS 的角度来看),要求人们以当地时区输入时间。但是为了正确进行转换,最好将该时间存储为 UTC。

Moment 本身可以帮助调整时间,例如

moment().subtract(4, 'hours');
moment().add(3, 'hours');

服务器端语言也可以提供帮助。例如,PHP 可以对时间进行数学运算

<?php var $sixHoursAgo = strtotime("-6 hours", time()); ?>

使用Moment Timezone 可能是最合理的方法,因为它并不总是精确的公式(再次 UGHADKGHK 夏令时)。

演示

在此演示中,我们使用 HTML5 时间输入并在运行时将其调整为本地化时间。

查看 Chris Coyier 在 CodePen 上的笔 将时间调整为本地时区@chriscoyier)。

其他方法

您是否有这方面的经验?您是如何处理的?

我们在此处使用的依赖项并非微不足道!似乎存在原生 JavaScript 方法(例如 getTimezoneOffset())具有相当好的支持,可以用于类似的效果。您是否有依赖这些方法的经验?