如何在JavaScript中处理时区「译」

611次阅读  |  发布于3年以前

在构建 Web 应用程序时,我们通常会考虑两种类型的时区。最常见的是服务器时间,它作为日期和时间跟踪的参考,非常简单。

但是,在某些情况下,我们需要跟踪最终用户的日期和时间。在这些情况下,我们需要使用 JavaScript 从用户的浏览器中捕获时间。此外,这些用户可能来自不同的时区,处理起来可能很棘手。

本文将讨论与时区相关的概念以及使用 JavaScript 处理它们的方法。

Time Zones GMT, Offset, UTC

不同时区

在深入了解细节之前,让我们了解一些有关时区的术语。

1 . GMT——通用参考

世界被划分为时区,每个时区都有其偏移量。此偏移量是添加到世界时间以获得每个国家/地区时区的分钟数。

为此,我们需要一个参考,即格林威治标准时间 (GMT)。它从北极到南极,经过伦敦旧皇家天文台的格林威治区。

如果您在格林威治子午线以东,您的当地时间通常比格林威治标准时间早(例如,中国当地时间是格林威治标准时间 +8 小时)。相反,当地时间在格林威治子午线以西的格林威治标准时间之后(例如,纽约当地时间在冬天是格林威治标准时间 -5 小时,在夏天是格林威治标准时间 -4 小时)。

2 . 偏移 - 与参考的差异

时区偏移GMT之前或之后的小时数或分钟数。

由于夏令时的原因,时区的偏移量可能会全年发生变化。此外,法律可以改变时区的偏移或夏令时时间表。例如,当我们说印第安纳州从中部时间切换到东部时间时,印第安纳州的时区从一个偏移量转移到另一个偏移量。

国家通常以自己的名字命名时区。例如,韩国的时区被称为 KST(韩国标准时间),它有一个特定的偏移值KST = UTC+09:00。

3 . UTC——更好的 GMT 替代方案

许多人错误地认为 GMT 和 UTC 是同一个东西,经常互换使用。但是如果我告诉你它们不一样呢?

UTC 于 1972 年创建,旨在解决地球自转减速问题。在这个基于国际原子时的时间系统中,铯原子频率用于设定时间标准。换句话说,UTC 是 GMT 的更好替代品。但是,对于日常开发而言,差异几乎不明显。

var d = new Date();
var n = d.getTimezoneOffset(); // 以分钟为单位返回 UTC 偏移量

在实践中使用 JavaScript 进行日期时间处理

JavaScript 为 Date 对象提供了各种方法来执行与日期和时间相关的计算。但是,您可以选择使用它或使用更多增强的库在代码中执行日期时间处理。让我们首先看看我们从 JavaScript 日期对象中得到了什么。

日期时间操作——使用纯 JavaScript

JavaScript 中的 Date 对象在内部使用绝对数字(例如 Unix 时间)管理时间数据。构造函数和方法,如parse(),getHour(),setHour().

但是,重要的是要注意它受客户端本地时区(准确地说是运行浏览器的操作系统的时区)的影响。因此,从用户输入数据生成 Date 对象将代表客户端的本地时区。日期对象在内部以 UTC 时间跟踪时间,但它通常以运行它的计算机的本地时间接受和输出数据。

但是,在 JavaScript 中,在处理跨不同时区的日期时间计算时,本机可用的方法有限。

但是,日期对象可以对非本地时区执行一项操作。

ISOString —它可以解析包含任何时区的数字 UTC 偏移量的文本。输出 Date 对象不保留原始本地时间和偏移量。

var d = new Date();
d.toISOString()  //=> "2021-09-06T13:52:23.770Z"
d.valueOf()  //=> 1630936367439  (this is what is actually stored in the object)

日期时间操作——使用第三方库

有许多库提供了广泛的日期格式和操作功能。我们可以根据它们是否支持ECMAScript 国际化 API 将这些库分为两种类型。

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl

基于国际标准的三方库

新的开发应该使用这些时区实现之一,它们使用 Intl API 来处理它们的数据:

非国际标准的三方库

这些库保持最新状态,但它们负责打包它们的时区数据,这些数据可能很大。

此外,必须避免为新项目使用一些已停止更新的库。

停止更新的三方库

这些库已退役,不应再使用。

其中,我相信你们中的大多数人都熟悉 Moment,但是,Moment 团队现在建议使用 Luxon 进行未来的开发。

当您尝试使用内置库时,我的建议是尝试使用其文档。然后,在您对基础知识有所了解后,尝试将其应用到您的代码中。

我的最爱——Date-fns

Date-fns 是一个小型库,具有简单的 API 和许多小功能。有近 140 个函数,Date-fn日期被称为 Lodash。

Date-fns 具有以下优点:

npm 包集合包括 Date-fns。您可以使用命令安装 date-fns。npm install date-fns.

Date-fns 兼容 CommonJS 和 ES 模块。

您需要导入开始解析和显示日期所需的函数;你不需要导入整个 API(只需要你需要的)。让我们只显示当前日期。

//Import the function initially
const {format} = require('date-fns');
//today's date
const today =format(new Date(),'dd.MM.yyyy');
console.log(today);

使用时区

为了使用 UTC 或 ISO 日期字符串,Date-fns 支持时区数据。这将允许您以用户的本地时间显示日期和时间。当使用多个时区时,挑战就来了。让我们通过一个例子来看看我们如何处理这些情况。

  1. 引用 — 首先,时间戳、UTC 或 ISO 日期字符串表示固定的时间点。
  2. 特定时区 - 其次,时区描述符(例如美国/洛杉矶)通常是偏移量或 IANA 时区名称。

注意:您需要使用 npm install date-fns-tz.

1 . 分区时间为 UTC

2 . UTC 到分区时间

结论

有几个库可用于处理时区。它们通常实现标准的 IANA 时区数据库并提供在 JavaScript 中使用它的函数,尽管它们不能使 Date 对象的行为有任何不同。

现代库使用 Intl API 的时区数据,而较旧的库通常有开销,尤其是在 Web 浏览器中运行时,因为数据库可能会变得相当大。

但是,如果您为新项目选择一个库,请选择一个支持 Intl API 的库,这可能是面向未来的。否则,如果您只处理几个 Date 时间操作,使用原生 Date 对象也可以。

我希望本文能帮助您确定在 JavaScript 中处理时区时要考虑的多个选项。如果您有任何其他建议,请在下面的评论中提供。

Copyright© 2013-2020

All Rights Reserved 京ICP备2023019179号-8