日期 Date

日期和时间?!] Date对象是 JS 中内置的数据类型,用于提供日期和时间的操作接口。

Date对象,是在早期 Java 中的 java.util.Date类 基础上创建的。为此,Date类型使用自 UTC 1970年1月1日0点开始经过的毫秒数来保存日期,它可以表示的时间范围是1970年1月1日0点前后的各1亿天。


静态方法 — 返回距UTC1970年1月1日0点开始的毫秒数(Number类型)

学习 Date 的构造函数前,先了解静态方法。因为 Date 对象的静态方法和其构造函数关系密切 — 使用构造函数创建 Date 对象的过程,就好像披着外套的静态方法的使用过程。

所谓静态方法,就是它们是通过 Date() 构造函数本身调用,而不是 Date 实例。一共有以下 3 个:

[1] Date.now()

ES5新增,返回一个Number类型的当前时间距离1970年1月1日0点UTC的毫秒数,不支持传参。

Date.now();   // 1468297046050
typeof Date.now();   // 'number'

在不支持 Date.now() 方法的浏览器中,可以用+操作符把Date对象转换成数字,也可以实现类似效果

new Date();    // Tue Jul 12 2016 12:21:33 GMT+0800 (中国标准时间)
+new Date();   // 1468297293433
+new Date(2000,1,1);   // 949334400000

// 代码示例:常用于分析代码的工作

var start = Date.now();
doSomething();
var stop = Date.now();
var result = stop - start;

[2] Date.parse()

解析一个日期字符串,参数是一个包含待解析的日期和时间的字符串,返回从1970年1月1日0点到给定日期的毫秒数。

该方法会根据日期时间字符串格式规则来解析字符串的格式,除了标准格式外,以下格式也支持:

  • 如果字符串无法识别,将返回NaN。
  • '月/日/年'     6/13/2004
  • '月 日,年' 如January 12,2004或Jan 12,2004
  • '星期 月 日 年 时:分:秒 时区' Tue May 25 2004 00:00:00 GMT-0700
Date.parse('6/13/2004');   // 1087056000000
Date.parse('January 12,2004');   // 1073836800000
Date.parse('Tue May 25 2004 00:00:00 GMT-0700');   // 1085468400000
Date.parse('2004-05-25T00:00:00');   // 1085443200000
Date.parse('2016');//1451606400000
Date.parse('T00:00:00');   // NaN   浏览器不支持只表示时间的字符串格式( 不表示日期 )
Date.parse();   // NaN

在 ES5 中,如果使用标准的日期时间字符串格式规则的字符串中,数学前有前置0,则会解析为UTC时间,没有前置0,则会解析为本地时间,其他情况一般都会解析为本地时间。

Date.parse('7/12/2016');   // 1468252800000
Date.parse('2016-7-12');   // 1468252800000
Date.parse('2016-07-12');   // 1468281600000

[3] Date.UTC()

返回给定日期的毫秒数,但其参数并不是一个字符串,而是分别代表年、月、日、时、分、秒、毫秒的数字参数

Date.UTC(year,month,day,hours,minutes,seconds,ms)

// year 和 month 参数是固定的,其余参数可选

该方法使用的是 UTC 时间,而不是本地时间。

Date.UTC(1970);   // NaN
Date.UTC(1970,0);   // 0
Date.UTC(1970,0,2);   // 86400000
Date.UTC(1970,0,1,1);   // 3600000
Date.UTC(1970,0,1,1,59);   // 714000
Date.UTC(1970,0,1,1,59,30);   // 717000

构造函数( 5 种 )

[1] Date()                 // 不带new操作符,实际上它不能称之为构造函数

Date();   // 像函数一样调用,它将忽略所有传入的参数,并返回当前日期和时间的字符串表示


Date();   // "Tue Jul 12 2016 13:38:41 GMT+0800 (中国标准时间)"
Date('2016/1/1');   // "Tue Jul 12 2016 13:38:41 GMT+0800 (中国标准时间)"
typeof Date();   // 'string'

[2] new Date()

  • 不带参数时,将根据当前时间和日期创建一个 Date 对象
new Date();   // Tue Jul 12 2016 13:41:45 GMT+0800 (中国标准时间)

typeof new Date();   // 'object'
  • 接受一个数字参数(该参数表示距1970年1月1日0点的毫秒数)
new Date(86400000);   // Fri Jan 02 1970 08:00:00 GMT+0800 (中国标准时间)

typeof new Date(0);   // object
  • 接受一个字符串参数( 参数形式类似于Date.parse()方法 )
Date.parse('6/13/2004');   // 1087056000000
typeof new Date(6/13/2004);   // object

// 关于标准的日期时间字符串中前置0的处理,也类似于Date.parse()方法。
  • 可接受参数形式类似于Date.UTC()方法的参数,但返回的是一个对象,且是本地时间
new Date(2016,7,12);   // Fri Aug 12 2016 00:00:00 GMT+0800 (中国标准时间)
+new Date(2016,7,12);   // 1470931200000
typeof new Date(2016,7,12);   // 'object'
Date.UTC(2016,7,12);   // 1470960000000
typeof Date.UTC(2016,7,12);   // 'number'

// 代码示例

<script>
	// 代码示例:计算时间差,返回相差的天、时、分、秒
	
	// 1. 两个日期对象如何相减
	// var d1 = new Date();
	// var d2 = new Date(2019,10,1);
	// 
	// console.log(d2-d1);  // 6856883740
	// 两个对象可以相减,实际为 d2.valueOf() - d1.valueOf() ,即两个时间相差的毫秒数

	// 2. 如何计算相差的天、时、分、秒
	// 相差的总毫秒数 6856883740
	// 相差的总的秒数 6856883740 / 1000
	// 
	// 相差的天数     6856883740 / 1000 / 60 / 60 / 24
	// 相差的小时数   6856883740 / 1000 / 60 / 60 % 24
	// 相差的分钟数   6856883740 / 1000 / 60 % 60
	// 相差的秒数     6856883740 / 1000 % 60
	
	function getInterval(start,end){
		// 两个日期对象相差的毫秒数
		var interval = end - start;

		// 求相差的天数、小时数、分钟数、秒数
		var day,hour,minute,second;
		interval = interval / 1000;  // 总的秒数

		day = Math.round(interval / 60 / 60 / 24);
		hour = Math.round(interval / 1000 / 60 / 60 % 24);
		minute = Math.round(interval / 1000 / 60 / 60 % 24);
		second = Math.round(interval / 1000 / 60 / 60 % 24);

		return {
			day:day,
			hour:hour,
			minute:minute,
			second:second
		}
	}
	var d1 = new Date();
	var d2 = new Date(2019,10,1);

	var obj = getInterval(d1,d2);
	console.log(obj.day + '天' + obj.hour + '小时' + obj.minute + '分' + obj.second + '秒');
</script>

实例方法

Date对象没有可以直接读写的属性,所有对日期和时间的访问都需要通过方法。

Date对象的方法分为两种形式:一种是使用本地时间,一种是使用UTC时间。分为to类、get类、set类。

说明:get[UTC]Day() 同时代表 getDay() 和 getUTCDay()。

[ to类 ] 日期格式化方法,从Date对象返回一个字符串,表示指定的时间。

  • toString():返回本地时区的日期字符串
  • toUTCString():返回UTC时间的日期字符串
  • toISOString():返回Date对象的标准的日期时间字符串格式的字符串
  • toJSON():返回一个符合JSON格式的日期字符串,与toISOString方法的返回结果完全相同

以下格式化日期的方法,在不同的浏览器中可能表现不一致,一般不用。

  • toDateString():返回Date对象的日期部分的字符串
  • toTimeString():返回Date对象的时间部分的字符串
new Date('2016-7-12').toString();   // Tue Jul 12 2016 00:00:00 GMT+0800 (中国标准时间)
new Date('2016-7-12').toUTCString();   // Mon, 11 Jul 2016 16:00:00 GMT
new Date('2016-7-12').toISOString();   // 2016-07-11T16:00:00.000Z
new Date('2016-7-12').toDateString();   // Tue Jul 12 2016
new Date('2016-7-12').toTimeString();   // 00:00:00 GMT+0800 (中国标准时间)
new Date('2016-7-12').toJSON();   // 2016-07-11T16:00:00.000Z
  • toLocaleString():toString()方法的本地化转换
  • toLocaleTimeString():toTimeString()方法的本地化转换
  • toLocaleDateString():toDateString()方法的本地化转换
new Date('2016-7-12').toString();   // Tue Jul 12 2016 00:00:00 GMT+0800 (中国标准时间)
new Date('2016-7-12').toLocaleString();   // 2016/7/12 上午12:00:00
new Date('2016-7-12').toDateString();   // Tue Jul 12 2016
new Date('2016-7-12').toLocaleDateString();   // 2016/7/12
new Date('2016-7-12').toTimeString();   // 00:00:00 GMT+0800 (中国标准时间)
new Date('2016-7-12').toLocaleTimeString();   // 上午12:00:00

[ get类 ] 获取日期指定部分,也就是说,用于获取实例对象某个方面的值

valueOf():返回距离1970年1月1日0点的毫秒数,因此,可以方便地使用比较运算符来比较日期值

// 学习 get 类方法之前,首先要了解 valueOf() 方法

   var date1 = new Date(2007,0,1);
   var date2 = new Date(2007,1,1);
   console.log(date1 > date2);   // false
   console.log(date1 < date2);   // true

getTime() 返回距离1970年1月1日0点的毫秒数,同valueOf()

// 在 ES5 之前,可以使用getTime()方法实现Date.now()
 
   Date.now = function(){
        return (new Date()).getTime()
    }

getTimezoneOffset() 返回当前时间与UTC的时区差异,以分钟表示(8*60=480分钟),返回结果考虑了夏令时因素

console.log(new Date('2016-7-12').valueOf());//1468252800000
console.log(new Date('2016-7-12').getTime());//1468252800000
console.log(new Date('2016-7-12').getTimezoneOffset());//-480

  • getYear():返回距离1900年的年数( 已过时 )
  • get[UTC]FullYear():返回年份(4位数)
  • get[UTC]Month():返回月份(0-11)
  • get[UTC]Date():返回第几天(1-31)
  • get[UTC]Day():返回星期几(0-6)
  • get[UTC]Hours():返回小时值(0-23)
  • get[UTC]Minutes():返回分钟值(0-59)
  • get[UTC]Seconds():返回秒值(0-59)
  • get[UTC]Milliseconds():返回毫秒值(0-999)
// 通过标准日期时间格式字符串,且有前置0的形式的参数设置,设置的是UTC时间

<script>
	// 代码示例:写一个函数,格式化日期对象,返回yyyy-MM-dd HH:mm:ss的形式
	function formateDate(date){
		// 判断参数date是否是日期对象
		if(!(date instanceof Date)){
			console.error("date不是日期对象");
			return;
		}		
		var year = date.getFullYear(),
			month = date.getMonth()+1,
			day = date.getDate(),
			hour = date.getHours(),
			minute = date.getMinutes(),
			second = date.getSeconds();
			
			// 如果是个位数,前面自动补‘0’,如 2017-8-13 和 2017-08-13
			month = month<10 ? '0'+ month : month;
			day = day<10 ? '0'+ day : day;
			hour = hour<10 ? '0'+ hour : hour;
			minute = minute<10 ? '0'+ minute : minute;
			second = second<10 ? '0'+ second : second;

		return year + "-" + month + "-" + day + " " + hour + ":" + minute + ":" + second;
	}
	var d = new Date();
	var dStr = formateDate(d);
	alert(dStr);
</script>

[3] set类 用于设置实例对象的各个方面,基本与get方法相对应。

set方法传入类似于Date.UTC()的参数,返回调整后的日期的内部毫秒数          // 星期只能获取,不能设置

  • setTime() 使用毫秒的格式,设置一个Date对象的值
var d = new Date('2016-07-12T10:00');
console.log(d.setTime(86400000),d);//86400000 Fri Jan 02 1970 08:00:00 GMT+0800 (中国标准时间)
  • setYear() 设置年份( 已过时 )
var d = new Date('2016-07-12T10:00');
console.log(d.setYear(2000),d,d.getYear());//963396000000 Wed Jul 12 2000 18:00:00 GMT+0800 (中国标准时间) 100

  • set[UTC]FullYear() 设置年份(4位数),以及可选的月份值和日期值
  • set[UTC]Month() 设置月份(0-11),以及可选的日期值
  • set[UTC]Date() 设置第几天(1-31)
var d = new Date('2016-07-12T10:00');
console.log(d.setFullYear(2015,1,1),d.getFullYear());//1422784800000 2015
console.log(d.setMonth(2),d.getMonth());//1425204000000 2
console.log(d.setDate(20),d.getDate());//1426845600000 20
console.log(d.toLocaleString());//2015/3/20 下午6:00:00
  • set[UTC]Hours() 设置小时值(0-23),以及可选的分钟值、秒值及毫秒值
  • set[UTC]Minutes() 设置分钟值(0-59),以及可选的秒值及毫秒值
  • set[UTC]Seconds() 设置秒值(0-59),以及可选的毫秒值
  • set[UTC]Milliseconds() 设置毫秒值(0-999)
var d = new Date('2016-07-12T10:20:30');
console.log(d.setHours(1,2,3),d.getHours());//1468256523000 1
console.log(d.setMinutes(2,3),d.getMinutes());//1468256523000 2
console.log(d.setSeconds(3),d.getSeconds());//1468256523000 3
console.log(d.toLocaleTimeString())//上午1:02:03
var d = new Date('2016-07-12T10:20:30');
console.log(d.setUTCHours(1,2,3),d.getHours());//1468285323000  9
console.log(d.setUTCMinutes(2,3),d.getMinutes());//1468285323000  2
console.log(d.setUTCSeconds(3),d.getSeconds());//1468285323000  3
console.log(d.toLocaleTimeString())//上午9:02:03