如何深入理解 JavaScript 中的日期(Date)和时间(Time)

卡拉先生
发布于 2020年07月07日 | 上次编辑:2020年07月22日

Javascript中的日期和时间
Javascript中的日期和时间

简介

日期和时间是我们日常生活的一个常规部分,因此在计算机编程中占据了显著位置。在 JavaScript 中,你可能需要创建一个包含日历、火车时间表或提醒你要跟妹子见面的日历界面的网站。

这些应用程序需要根据用户的当前时区显示相关的时间,或者完成到达、离开,以及开始和结束时的计算。此外,你可能需要使用 JavaScript 在每天的特定时间生成报告,或者筛选目前开门的餐厅和场所。

为了实现上述需求,JavaScript 附带了内置的 Date 对象和相关方法。本教程将介绍如何在 JavaScript 中格式化以及使用日期和时间。

Date 对象

Date 对象是 JavaScript 中存储日期和时间的内置对象。它提供了许多用于格式化和管理数据的内置方法。

默认情况下,没有提供参数的新 Date 实例将创建一个与当前日期和时间相对应的对象。这将根据当前系统的系统设置创建。

为了演示 JavaScript 的Date,让我们创建一个变量,并为其分配当前日期。本文写于 10 月 18 日星期三,旧金山时间,因此下面是当前的日期、时间和时区。

// Set variable to current date and time
const now = new Date();

// View the output
now;
// Output
Tue Jul 21 2020 21:08:54 GMT-0700 (Pacific Daylight Time)

看看输出的结果,我们有一个日期字符串,包含以下内容:

Day of the Week Month Day Year Hour Minute Second Timezone
Wed Jul 21 2020 21 08 54 GMT-0700

日期和时间以我们人类能够理解的方式被断句和打印。

但是,JavaScript 基于从 Unix 时间派生的时间戳来理解日期。该时间戳是一个值,由自 1970 年 1 月 1 日午夜以来经过的毫秒数组成。我们可以用 getTime() 方法获取时间戳。

// Get the current timestamp
now.getTime();
// Output
1595391075860

当前时间戳输出显示的很大的数字表示与上述值相同的值,即 2020 年 07 月 21 日。

纪元时间(也称为零时间)由日期字符串 1970 年 1 月 1 日 00:00:00 世界时(UTC)0 时间戳表示。我们可以在浏览器中通过创建新变量,并基于 0 的时间戳为其分配一个新的 Date 实例来测试这一点。

// Assign the timestamp 0 to a new variable
const epochTime = new Date(0);

epochTime;
// Output
01 January, 1970 00:00:00 Universal Time (UTC)

在编程语言刚出现的时候,UTC 时间被选为计算机测量时间的标准,它也是 JavaScript 使用的标准。理解时间戳和日期字符串的概念非常重要,因为根据不同的情况你可能需要转换它们,以及在不同的场景下替换使用。

卡拉搜索的 API 中,我们统一使用和返回 UTC 时间,这样也方便用户在使用的时候,避免时区混淆。如果你也希望为用户提供更加友好的 API 的话,推荐阅读:REST API 设计的最佳实践

到目前为止,我们学习了如何基于当前时间创建新的 Date 实例,以及如何基于时间戳创建一个新的 Date 实例。总的来说,有四种格式可以用来在 JavaScript 中创建新的Date。除了当前的默认时间和时间戳,你还可以使用日期字符串,或者指定特定的日期和时间。

Date Creation Output
new Date() 当前日期和时间
new Date(timestamp) 根据一个时间戳来创建日期和时间
new Date(date string) 根据一个日期字符串来创建 Date
new Date(year, month, day, hours, minutes, seconds, milliseconds) 根据具体的时间来创建一个 Date

为了演示引用特定日期的不同方式,我们将创建新的 Date 对象,该对象以三种不同的方式表示 1776 年 7 月 4 日,格林尼治标准时间下午 12:30。

// Timestamp method
new Date(-6106015800000);

// Date string method
new Date("January 31 1980 12:30");

// Date and time method
new Date(1776, 6, 4, 12, 30, 0, 0);

以上三个示例都创建了一个包含相同信息的日期。

你会注意到时间戳方法有一个负数;纪元时间之前的任何日期都将表示为负数。

在日期和时间方法中,我们的秒和毫秒均设置为 0。如果 Date 创建中缺少任何数字,则默认为 0。然而,顺序是不能改变的,所以如果你决定保留一个数字,请记住这一点。你可能还会注意到,7 月由 6 表示,而不是通常的 7。这是因为日期和时间编号从 0 开始,就像编程中的大多数计数一样。更详细的图表参见下一节。

get 方法检索日期

一旦我们有了日期,我们就可以用各种内置的方法访问日期的所有组成部分。方法将返回相对于本地时区的日期的每个部分。这些方法中的每一个都从 get 开始,并将返回相应的数字。下面是 Date 对象的 get 方法的详细列表。

Date/Time Method Range Example
Year getFullYear() YYYY 1970
Month getMonth() 0-11 0 = 一月
Day (of the month) getDate() 1-31 1 = 一个月中的第一天
Day (of the week) getDay() 0-6 0 = 周日
Hour getHours() 0-23 0 = 午夜 0 点
Minute getMinutes() 0-59
Second getSeconds() 0-59
Millisecond getMilliseconds() 0-999
Timestamp getTime() Milliseconds since Epoch time

让我们根据 1980 年 7 月 31 日创建一个新的日期,并将其赋值给变量。

// Initialize a new birthday instance
const birthday = new Date(1980, 6, 31);

现在,我们可以使用所有的方法获取每个日期组件,从年到毫秒。

birthday.getFullYear();      // 1980
birthday.getMonth();         // 6
birthday.getDate();          // 31
birthday.getDay();           // 4
birthday.getHours();         // 0
birthday.getMinutes();       // 0
birthday.getSeconds();       // 0
birthday.getMilliseconds();  // 0
birthday.getTime();          // 333849600000 (for GMT)

有时可能只需要提取日期的一部分,而内置的 get 方法是你实现此目的的工具。

例如,我们可以根据 10 月 3 日的日期和时间测试当前日期,以查看它是否是 10 月 3 日。

// Get today's date
const today = new Date();

// Compare today with October 3rd
if (today.getDate() === 3 && today.getMonth() === 9) {
  console.log("It's October 3rd.");
} else {
  console.log("It's not October 3rd.");
}
// Output
It's not October 3rd.

这是因为在编写本文时不是 10 月 3 日,控制台里的输出也反映了这一点。

get 开头的内置 Date 方法允许我们访问日期组件,这些组件返回与我们从实例化对象中检索到的编号相关联的数字。

set 方法修改日期

对于我们在上面学到的所有 get 方法,都有一个对应的 set 方法。其中 get 用于从日期中检索特定的组件,set 则用于修改日期的组件。下面是 Date 对象的 set 方法的详细列表。

Date/Time Method Range Example
Year setFullYear() YYYY 1970
Month setMonth() 0-11 0 = 一月
Day (of the month) setDate() 1-31 1 = 一个月的第1天
Day (of the week) setDay() 0-6 0 = 周日
Hour setHours() 0-23 0 = 午夜 0 点
Minute setMinutes() 0-59
Second setSeconds() 0-59
Millisecond setMilliseconds() 0-999
Timestamp setTime() Milliseconds since Epoch time

我们可以使用这些 set 方法修改日期的一个、多个以及所有组件。例如,我们可以将 birthday 变量的年数从上面更改为 1997 年而不是 1980 年。

// Change year of birthday date
birthday.setFullYear(1997);

birthday;
// Output
Thu Jul 31 1997 00:00:00 GMT+0000 (UTC)

我们在上面的示例中看到,当我们调用 birthday 变量时,我们会将新的一年作为输出的一部分。

set 开头的内置方法允许我们修改 Date 对象的不同部分。

世界协调时的日期方法

上面讨论的 get 方法根据用户的本地时区设置检索日期组件。为了增加对日期和时间的控制,你可以使用 getUTC 方法。这些方法与 get 方法完全相同,只是它们基于 UTC(协调通用时间)标准计算时间。下面是 JavaScript Date 对象的 UTC 方法表。

Date/Time Method Range Example
Year getUTCFullYear() YYYY 1970
Month getUTCMonth() 0-11 0 = January
Day (of the month) getUTCDate() 1-31 1 = 1st of the month
Day (of the week) getUTCDay() 0-6 0 = Sunday
Hour getUTCHours() 0-23 0 = midnight
Minute getUTCMinutes() 0-59
Second getUTCSeconds() 0-59
Millisecond getUTCMilliseconds() 0-999

为了测试本地和 UTC get 方法的区别,我们可以运行如下代码。

// Assign current time to a variable
const now = new Date();

// Print local and UTC timezones
console.log(now.getHours());
console.log(now.getUTCHours());

运行此代码将打印当前小时和 UTC 时区的小时。如果你当前位于 UTC 时区,运行上述程序输出的数字将相同。

UTC 非常有用,因为它提供了国际时间标准参考,因此,如果适用于你正在开发的内容,它可以保持你的代码跨时区一致。在绝大多数场景中,时间的运算应该转为 UTC 时间,显示时再以用户当前时区来显示,这样可以极大程度上避免混乱。同时也推荐用一些时间库,比如 moment.js 来操作时间。

结论

在本节教程中,我们学习了如何创建 Date 对象的实例,并使用其内置方法访问和修改特定日期的组件。要更为深入地了解 JavaScript 中的日期和时间,你可以阅读 Mozilla 开发者网络上的日期部分说明。

知道如何处理日期对于 JavaScript 中的许多常见任务来说是至关重要的,因为这可以让你做很多事情,从跑一个 cron job 到正确地根据不同时区显示用户的时间。

友情链接更新日志© 2020, 卡拉搜索, Built with ❤️ in San Francisco + Beijing

京ICP备15049164号-3