DanLevy.net

测验:14个JavaScript日期问题

学会用JS冷知识在聚会上脱颖而出!✨

Hero image for 测验:14个JavaScript日期问题

你对 Date 类的了解程度如何?

证明你的 JavaScript 技能! 🚀
无需登录或注册。
多选题。 🤖 … 这能有多难,对吧?

内容概要

JavaScript 中的 Date 类拥有臭名昭著的复杂 API。它从 Java 继承而来,我只能推测其设计灵感源自远古的石器时代计时方法。

获取 Date 实例的困难程度,使得许多开发者毫不犹豫地转向第三方库。虽然这些库通常是安全可靠的选择,但它们在日期格式化或本地化场景中往往并不必要!

本测验旨在测试(并加深)你对原生 Date API 的理解。点击绿色按钮获取提示和解释!希望在完成挑战后,你能牢固掌握 JavaScript 中 Date 的用法。

注意: 所有示例均假设使用 GMT-7 本地时区。

👇 以下 14 道题目 👇

输出将包含什么?

const d1 = new Date(2020, 1, 1)
console.log(d1)

月份参数是零索引的。范围是0-11(使用西方日历)。

‘二月’的索引值是1。(想想数组查找的方式)

输出将包含什么?

const d2 = new Date(2020, 0, 1)
console.log(d2)

月份参数是基于零的。在使用西方日历时,范围是0到11。

‘一月’的索引值为零。(可以将其视为数组查找。)

输出将包含什么?

const d3 = Date('Thu, 01 Jan 1970 00:00:00 GMT')
console.log(d3)

别忘了new关键字!Date是一个类,应该用new调用。

不带newDate('...')会忽略你传入的内容。它似乎总是通过new Date()(无参数)生成当前日期和时间。

这是一个常见陷阱容易被忽视,即使是在代码审查中也是如此。

输出将包含什么?

const date = new Date(2020)
console.log(date.getFullYear())

使用单个整数参数创建的Date实例会被解释为Unix时间戳。时间戳是自1970年1月1日以来的毫秒数。

2020(毫秒)对应的是1970年1月1日之后的2秒。

由于本地时区有-7小时的负偏移,最终结果会是Wed Dec 31 1969 17:00:02 GMT-0700 (Mountain Standard Time)

可以通过使用.getUTCFullYear()跳过本地时区偏移。

什么值会打印到控制台?

const d1 = new Date('2020-01-01')
const d2 = new Date('2020-01-01T00:00')
console.log(d1.getFullYear(), d2.getFullYear())

缺少T时间值的字符串看似是2020年1月1日 - 但仅包含日期的字符串会被解释为UTC时间。当调整到本地时区(GMT-7)时,我们发现其实还在2019年。

没有显式时区的日期时间字符串会被解释为本地时间。

T00:00格式会让第二个值被解释为本地午夜时间。

第一个日期被解释为Tue Dec 31 2019 17:00:00 GMT-0700 (Mountain Standard Time)。 第二个日期被解释为Wed Jan 01 2020 00:00:00 GMT-0700 (Mountain Standard Time)

选择一个_错误_的格式化方法:

toLocaleFormat()方法不是标准的!它可能看起来很眼熟,因为它来自一个古老的第三方库。

查看toLocaleDateString文档方法。它的行为在Intl.DateTimeFormat中进行了文档说明。

输出将包含什么?

var date = Date.UTC('2020-01-02T00:00')
console.log(date.toUTCString())

你会得到 TypeError: date.toUTCString is not a function,因为 Date.UTC() 返回的是毫秒整数而非日期实例。

输出将包含什么?

const d = Date.UTC(2020, 0, 1)
console.log(d)

辅助方法Date.UTC不会返回日期实例。它返回的是以毫秒为单位的整数。

输出将包含什么?

// Assume local TZ is -07:00
const d = new Date(Date.UTC(2020, 0, 1))
console.log(d.getTimezoneOffset())

日期对象会以本地时间隐式呈现,其 .getTimezoneOffset() 会保持(实际上)不变。

Date 实例不会存储时区数据。它们存储的是自 Unix 纪元(1970 年 1 月 1 日)以来的毫秒数。时区在日期字符串解析和渲染时被考虑。默认显示行为基于系统或浏览器的区域设置自动确定。

输出将包含什么?

const d = new Date(2020, 0, 1)
d.setDate(1)
console.log(d)

.setDate() 方法会根据给定实例的当前月份设置日期。

如果提供的值超过了该月的天数范围,日期实例的月份值会自动调整(例如:setDate(32) 在1月会计算为2月1日)。

输出将包含什么?

const d = new Date(2020, 0, 1)
d.setMonth(1)
console.log(d)

.setMonth() 方法会设置给定日期实例的月份。

月份参数是从0开始的,范围是0-11(使用西方日历)。

输出将包含什么?

const d = new Date(2020, 0, 1)
d.setMonth(12)
console.log(d)

.setMonth() 方法会设置给定日期实例的月份。

month 参数是基于零的(zero-based),在西方日历中取值范围为 0-11(12 个值)。

在这里我们看到年份被调整为 2021 年,因为 setMonth(12) 比 11(12 月)多 1。

输出将包含什么?

const d = new Date(2020, 0, 1)
d.setMonth(13)
console.log(d)

.setMonth() 方法设置给定日期实例的月份。

月份参数是零基索引,范围为0-11(使用西方日历)。

在这里我们看到月份和年份调整为2021年2月,因为 setMonth(13) 比11(12月)多出2个月。

输出将包含什么?

const d = new Date(2020, 0, 1)
d.setMonth(-1)
console.log(d)

.setMonth() 方法设置给定日期实例的月份。

月份参数是从0开始计算的(使用公历),范围为0-11。

这里我们看到月份和年份回滚到2019年12月,因为 setMonth(-1) 小于0(即1月)。