Skip to content
快速预览

Date对象

✍️ cyyspring 🕒 2023-08-11 01:54:57(9 months ago) 🔗 A.前端知识整理

Date 对象在 JavaScript 中表示时间的单个瞬间。它可以用于执行各种与日期和时间相关的操作,例如创建、格式化和解析日期。

在 JavaScript 中,使用 Date 对象创建的日期和时间是基于 UTC 的,但是在输出时会根据本地时区进行调整。所以,可以说 Date 对象创建的是 UTC 时间。

  • GMT是英国伦敦的皇家格林威治( Greenwich )天文台的标准时间(刚好在本初子午线经过的地方)往的时区时间晚(表示为 GMT+hh:mm)、往西的时区时间早(表示为 GMT-hh:mm) 例子说明:Sat Jul 09 2022 09:38:28 GMT+0800 (中国标准时间) 中国是东八区

  • UTC 产生因为公转有一定的误差,也会造成GMT的时间会造成一定的误差,于是就提出了根据原子钟计算的标准时间UTC(Coordinated Universal Time),UTC 是一种标准时间,它是根据原子钟计算的,用于避免地球自转引起的误差。而本初子午线是一个经度线,它被定义为经过英国伦敦的那条经线。UTC 时间是以本初子午线为基准的,因此可以将 UTC 看作是本初子午线时间的替代。

:GMT依然在使用,主要表示的是某个时区中的时间,而UTC是标准的时间

两种时间格式

  1. Thu Jan 01 1970 08:00:01 GMT+0800 (中国标准时间) -- 是RFC 2822标准

RFC2822:用于在 HTTP 和电子邮件标题等位置统一表示日期和时间的互联网信息格式。RFC 2822 包括星期几(短)、数字日期、月份的三字母缩写、年、时间和时区

  1. 2022-07-09T02:14:44.989Z -- ISO 8601标准

ISO8601,全称为《数据存储和交换形式·信息交换·日期和时间的表示方法》,规定了国际标准日期与时间表示法。

  • 只使用数字为基本格式。使用短横线"-"间隔开年、月、日为扩展格式。
  • 每个日期和时间值都有一个固定的位数,必须用前导零填充。
  • 日期时间表示只能有数字或少数特殊字符组成(如“ - ”,“:”,“T”,“W”和“Z”),不允许出现地方写法,如“1月”或“星期四”等。
  • ISO 8601使用24小时制。HH:MM:SS.sss,HH:MM:SS,HH:MM,HH为合规的时间格式。
  • 用字母T分隔日期和时间。如  20180703T224426Z   或  2018-07-03T22:44:26Z 。

ISO 8601标准 个参数说明,YYYY:年份,0000 ~ 9999,MM:月份,01 ~ 12,DD:日,01 ~ 31 T:分隔日期和时间,没有特殊含义,可以省略,HH:小时,00 ~ 24,mm:分钟,00 ~ 59,ss:秒,00 ~ 59,sss:毫秒,Z:时区

计算机中时间

以前的Unix操作系统中存储时间,是以32位有符号数来存储的。用32位来表示时间的最大间隔是68年,而最早出现的UNIX操作系统考虑到计算机产生的年代和应用的时限综合取了1970年1月1日0时0分0秒作为UNIX TIME的纪元时间(开始时间),将1970年作为中间点,向左向右偏移都可以照顾到更早或者更后的时间,因此将1970年1月1日0点作为计算机表示时间的原点,从1970年1月1日开始经过的秒数存储为一个32位整数。以后计算时间就把这个时间(1970年1月1日00:00:00)当做时间的零点。这种高效简洁的时间表示法,就被称为"Unix时间纪元"。

由浅入深,走进中级工程师都未必知道的 JavaScript 时间处理冷知识

Date 语法

js
new Date(); // 打印结果为当前地区时间
// 打印结果
Sat Jul 09 2022 09:49:39 GMT+0800 (中国标准时间)

new Date('2022-07-09') // 传入时间格式字符串 这种不推荐 字符串格式 2022/07/09 等等
// 打印结果
Sat Jul 09 2022 08:00:00 GMT+0800 (中国标准时间)

new Date(2022,07,07) // 注1 new Date(year, monthIndex [, day [, hours [, minutes [, seconds [, milliseconds]]]]]);
// 打印结果
Sun Aug 07 2022 00:00:00 GMT+0800 (中国标准时间)

new Date(1000)  // 传入是数字,会被当做毫秒处理表示从1970-01-01 00:00:00 UTC 经过的毫秒数
// 打印结果
Thu Jan 01 1970 08:00:01 GMT+0800 (中国标准时间)

new Date().toISOString() // 打印ISO8601格式
// 打印结果
'2022-07-09T02:14:44.989Z'

当 Date 作为构造函数调用并传入多个参数时,如果数值大于合理范围时(如月份为 13 或者分钟数为 70),相邻的数值会被调整。比如 new Date(2013, 13, 1) 等于 new Date(2014, 1, 1),它们都表示日期 2014-02-01(注意月份是从 0 开始的)。其他数值也是类似,new Date(2013, 2, 1, 0, 70) 等于 new Date(2013, 2, 1, 1, 10),都表示同一个时间:2013-03-01T01:10:00

获取时间戳

  • Unix 时间戳:它是一个整数值,表示自1970年1月1日00:00:00 UTC以来的毫秒数
  1. new Date().getTime()
  2. new Date().valueOf()
  3. +new Date()
  4. Date.now()
  5. Date.parse(dateString) 等同于 new Date(dateString).getTime() 操作 举个例子,需要符合 RFC2822 或 ISO 8601 日期格式的字符串; 比如YYYY-MM-DDTHH:mm:ss.sssZ,如果输入的格式不能被解析,那么会返回NaN Date.parse('2022-07-09T02:14:44.989Z') 打印结果1657332884989

从Date对象中获取

  1. getFullYear():获取年份(4 位数);
  2. getMonth():获取月份,从 0 到 11;
  3. getDate():获取当月的具体日期,从 1 到 31;
  4. getHours():获取小时;
  5. getMinutes():获取分钟;
  6. getSeconds():获取秒钟;
  7. getMilliseconds():获取毫秒;
  8. getDay() 获取一周中的第几天,从 0(星期日)到 6(星期六)

从 Date 中赋值

  1. setFullYear(year, [month], [date])
  2. setMonth(month, [date])
  3. setDate(date)
  4. setHours(hour, [min], [sec], [ms])
  5. setMinutes(min, [sec], [ms])
  6. setSeconds(sec, [ms])
  7. setMilliseconds(ms)
  8. setTime(milliseconds)
  • 注: 设置超范围的数值,它会自动校准

JS判断某年某月有多少天

在JavaScript中,当使用Date构造函数并传入特定参数时,有一些规则:

  1. 月份是从0开始计数的,即一月是0,二月是1,依此类推,十二月是11。
  2. 如果传入的日期为0,JavaScript会将其解释为所指定月份的最后一天。它会自动计算该月有多少天,并返回该月的最后一天的日期。
  3. 如果传入的月份超过了合法的范围(0到11),JavaScript会相应地调整年份。例如,传入13作为月份会将年份加1,传入-1会将年份减1。

因此,如果我们想知道某年某月有多少天,可以使用以下步骤:

使用new Date(year, month + 1, 0)构造一个Date对象,其中year是年份,month是月份。JavaScript会自动将传入的月份加1,并将日期设置为0,从而得到指定月份的最后一天的日期。

js
function getDaysInMonth(year,month){
  let temp = new Date(year,month,0);
  return temp.getDate();
}
getDaysInMonth(2019,2) //28 
getDaysInMonth(2020,2) //29

获取倒计时七天

当使用 new Date(now - 24 * 60 * 60 * 1000) 来计算前一天的日期时,它通常可以正常工作,即使是在月末。

无论当前日期是月末还是其他日期,该操作都会准确地计算前一天的日期。例如,如果当前日期是 2023 年 8 月 31 日,那么通过 new Date(now - 24 * 60 * 60 * 1000) 可以得到 2023 年 8 月 30 日

js
let now = new Date(); 
let s = '';
let i = 0;
while (i < 7) {
    s += now.getFullYear() + '/' + (now.getMonth() + 1) + '/' + now.getDate() + '\n';
    now = new Date(now - 24 * 60 * 60 * 1000); 
    i++;
}
/**
 * 2023/8/10
		2023/8/9
		2023/8/8
		2023/8/7
		2023/8/6
		2023/8/5
		2023/8/4
 */
console.log(s);

2038年问题

Unix时间戳是从1970年1月1日(UTC/GMT的午夜)开始所经过的秒数,不考虑闰秒。在32位系统上,time_t能表示的最大值为0x7ffffffff,当time_t取最大值时表示系统时间为2038-01-19 03:14:07,但时间再往后走时,那time_t会溢出变成一个负值,此时系统时间会倒流回到1901年,届时操作系统和上层软件都会运行出错。

解决这个问题最简单粗暴的方法是用64位来表示时间。64位表示时间的最大值是2900亿年后的292,277,026,596年12月4日15:30:08,星期日(UTC)(北京时间292,277,026,596年12月4日23:30:08)。实际上,大部份64位操作系统已经把time_t改为64位整型,对于这些机器来说,2038年问题不复存在。然而对于嵌入式设备来说,现在还有大量32位系统在全球各地运行,谁也无法保证这些系统在2038年之前就能光荣退役。另外对于64位操作系统,上面还会运行着32位的应用程序,依旧会发生2038年问题。

Released under the MIT License.