JavaScript初探系列(三)——日期对象
时间对象是一个我们经常要用到的对象,无论是做时间输出、时间判断等操作时都与这个对象离不开。它是一个内置对象——而不是其它对象的属性,允许用户执行各种使用日期和时间的过程。
一 、Date日期对象
(一)、创建日期
日期对象可以储存任意一个日期,并且可以精确到毫秒数(1/1000 秒)。定义一个时间对象 :
var today = new Date(); // 获取当前时间 var today = new Date(1453094034000);//传递毫秒 var birthday = new Date('December 17,1995'); var birthday = new Date('1995-12-17T03:24:00'); var birthday1 = new Date(1995,11,17,3,24,0);//传递日期时分秒 birthday1.toLocaleString() // "1995/12/17 上午3:24:00"
注意:使用关键字new,Date()的首字母必须大写。
二 、Date对象方法
(一)、常用方法列表
Date对象中的具体方法主要可以分为两大类:
- 一类是设置时间的方法(这里我暂且把它叫做set时间方法)
- 一类是获取时间的方法(这里我暂且把它叫做get时间方法)。
而这两类中的方法又分操作本地时间和UTC时间两种。
具体的方法有:
注意:
get、set UTC时间的方法和get、set本地方法是相似的,只不过其时间表示时的相对时区不一样而已,set时间的方法中的参数类型是整数类型。其中的参数没有大小的限制。比如:setMonth(mm)方法,可能你认为mm的大小会限制在0-11之间,其实不然,据验证,当其参数超过了11时,比如D.setMonth(12),该方法就会将D时间对象存储的年份进位1个单位,这有些像二进制、八进制、十进制中的逢二进一、逢八进一、逢十进一一样的道理。set时间的方法中没有setDay()和setUTCDay()(可能是因为在现实中应用不大,也没有意义吧,毕竟一周就7天,要设置用setDate()或setUTCDate()代替就好啦)。另外,get时间的方法中没有getUTCTime(),因为getTime()方法是获取1970年1月1日到当前时间的毫秒数,它是一个相对值,所以就算有getUTCTime()方法,它也是和getTime()返回相同的值,
注意Date对象中的方法是用于处理时间日期的,是相对人类定义的某种方式(比如UTC时间)来显示的时间,而非用于换算,这一点博主本人刚开始接触JS的时候就经常傻傻分不清楚的。比如:3605h→通过getSeconds()的运算后→5s,其计算经过是: ss=3605(h)%3600(s/h)=5s,而非 ss=3600(s/h)*3605(h) 这种计算
(二) 返回/设置年份方法
get/setFullYear()
返回/设置年份,用四位数表示。
var mydate=new Date();//当前时间2014年3月6日 document.write(mydate+"<br>");//输出当前时间 document.write(mydate.getFullYear()+"<br>");//输出当前年份 mydate.setFullYear(2018); //设置年份 document.write(mydate+"<br>"); //输出年份被设定为2018年。
结果:
Thu Mar 06 2014 10:57:47 GMT+0800
2014
Thu Mar 06 2018 10:57:47 GMT+0800
注意:
1.结果格式依次为:星期、月、日、年、时、分、秒、时区。(火狐浏览器)
2. 不同浏览器,时间格式有差异。
(三)返回/设置月份方法
getMonth() 返回月份,返回值是 0(一月) 到 11(十二月)之间的一个整数。如果要返回相对应月份,我们将创建一个数组,代码如下:
var d=new Date()
var month=new Array(12)
month[0]="January"
month[1]="February"
month[2]="March"
month[3]="April"
month[4]="May"
month[5]="June"
month[6]="July"
month[7]="August"
month[8]="September"
month[9]="October"
month[10]="November"
month[11]="December"
document.write("The month is " + month[d.getMonth()])
结果:
The month is July
(四)、返回星期方法
getDay() 返回星期,返回的是0-6的数字,0 表示星期天。如果要返回相对应“星期”,通过数组完成,代码如下:
var mydate=new Date();//定义日期对象 var weekday=["星期日","星期一","星期二","星期三","星期四","星期五","星期六"]; //定义数组对象,给每个数组项赋值 var mynum=mydate.getDay();//返回值存储在变量mynum中 document.write(mydate.getDay());//输出getDay()获取值 document.write("今天是:"+ weekday[mynum]);//输出星期几 执行结果:今天是:星期五
(五)返回/设置时间方法
get/setTime() 返回/设置时间,单位毫秒数,计算从 1970 年 1 月 1 日零时到日期对象所指的日期的毫秒数。
如果将目前日期对象的时间推迟1小时,代码如下:
var mydate=new Date(); document.write("当前时间:"+mydate+"<br>"); mydate.setTime(mydate.getTime() + 60 * 60 * 1000); document.write("推迟一小时时间:" + mydate);
结果:
当前时间:Thu Mar 6 11:46:27 UTC+0800 2014
推迟一小时时间:Thu Mar 6 12:46:27 UTC+0800 2014
注意:1. 一小时 60 分,一分 60 秒,一秒 1000 毫秒
2. 时间推迟 1 小时,就是: “x.setTime(x.getTime() + 60 * 60 * 1000);”
三、常用日期方法封装
(一)、日期格式化
1、使用说明
formatDate(date, fmt),其中fmt支持的格式有:
- y(年)
- M(月)
- d(日)
- q(季度)
- w(星期)
- H(24小时制的小时)
- h(12小时制的小时)
- m(分钟)
- s(秒)
- S(毫秒)
另外,字符的个数决定输出字符的长度,如,yy
输出16,yyyy
输出2016,ww
输出周五,www
输出星期五,等等。
/** * 将日期格式化成指定格式的字符串 * @param date 要格式化的日期,不传时默认当前时间,也可以是一个时间戳 * @param fmt 目标字符串格式,支持的字符有:y,M,d,q,w,H,h,m,S,默认:yyyy-MM-dd HH:mm:ss * @returns 返回格式化后的日期字符串 */ function formatDate(date, fmt) { date = date == undefined ? new Date() : date; date = typeof date == 'number' ? new Date(date) : date; fmt = fmt || 'yyyy-MM-dd HH:mm:ss'; var obj = { 'y': date.getFullYear(), // 年份,注意必须用getFullYear 'M': date.getMonth() + 1, // 月份,注意是从0-11 'd': date.getDate(), // 日期 'q': Math.floor((date.getMonth() + 3) / 3), // 季度 'w': date.getDay(), // 星期,注意是0-6 'H': date.getHours(), // 24小时制 'h': date.getHours() % 12 == 0 ? 12 : date.getHours() % 12, // 12小时制 'm': date.getMinutes(), // 分钟 's': date.getSeconds(), // 秒 'S': date.getMilliseconds() // 毫秒 }; var week = ['天', '一', '二', '三', '四', '五', '六']; for(var i in obj) { fmt = fmt.replace(new RegExp(i+'+', 'g'), function(m) { var val = obj[i] + ''; if(i == 'w') return (m.length > 2 ? '星期' : '周') + week[val]; for(var j = 0, len = val.length; j < m.length - len; j++) val = '0' + val; return m.length == 1 ? val : val.substring(val.length - m.length); }); } return fmt; }
2、使用示例
formatDate(); // 2016-09-02 13:17:13 formatDate(new Date(), 'yyyy-MM-dd'); // 2016-09-02 // 2016-09-02 第3季度 星期五 13:19:15:792 formatDate(new Date(), 'yyyy-MM-dd 第q季度 www HH:mm:ss:SSS'); formatDate(1472793615764); // 2016-09-02 13:20:15
(二)、日期解析
1、使用说明
parseDate(str, fmt),其中fmt支持的格式有:
- y(年)
- M(月)
- d(日)
- H(24小时制的小时)
- h(12小时制的小时)
- m(分钟)
- s(秒)
- S(毫秒)
/** * 将字符串解析成日期 * @param str 输入的日期字符串,如'2014-09-13' * @param fmt 字符串格式,默认'yyyy-MM-dd',支持如下:y、M、d、H、m、s、S,不支持w和q * @returns 解析后的Date类型日期 */ function parseDate(str, fmt) { fmt = fmt || 'yyyy-MM-dd'; var obj = {y: 0, M: 1, d: 0, H: 0, h: 0, m: 0, s: 0, S: 0}; fmt.replace(/([^yMdHmsS]*?)(([yMdHmsS])\3*)([^yMdHmsS]*?)/g, function(m, $1, $2, $3, $4, idx, old) { str = str.replace(new RegExp($1+'(\\d{'+$2.length+'})'+$4), function(_m, _$1) { obj[$3] = parseInt(_$1); return ''; }); return ''; }); obj.M--; // 月份是从0开始的,所以要减去1 var date = new Date(obj.y, obj.M, obj.d, obj.H, obj.m, obj.s); if(obj.S !== 0) date.setMilliseconds(obj.S); // 如果设置了毫秒 return date; }
2、使用示例
parseDate('2016-08-11'); // Thu Aug 11 2016 00:00:00 GMT+0800 parseDate('2016-08-11 13:28:43', 'yyyy-MM-dd HH:mm:ss') // Thu Aug 11 2016 13:28:43 GMT+0800
(三)、其他使用相关方法
/** * ===================================== * 日期相关方法 * ===================================== */ ;(function($) { $.extend( { /** * 将日期格式化成指定格式的字符串 * @param date 要格式化的日期,不传时默认当前时间,也可以是一个时间戳 * @param fmt 目标字符串格式,支持的字符有:y,M,d,q,w,H,h,m,S,默认:yyyy-MM-dd HH:mm:ss * @returns 返回格式化后的日期字符串 */ formatDate: function(date, fmt) { date = date == undefined ? new Date() : date; date = typeof date == 'number' ? new Date(date) : date; fmt = fmt || 'yyyy-MM-dd HH:mm:ss'; var obj = { 'y': date.getFullYear(), // 年份,注意必须用getFullYear 'M': date.getMonth() + 1, // 月份,注意是从0-11 'd': date.getDate(), // 日期 'q': Math.floor((date.getMonth() + 3) / 3), // 季度 'w': date.getDay(), // 星期,注意是0-6 'H': date.getHours(), // 24小时制 'h': date.getHours() % 12 == 0 ? 12 : date.getHours() % 12, // 12小时制 'm': date.getMinutes(), // 分钟 's': date.getSeconds(), // 秒 'S': date.getMilliseconds() // 毫秒 }; var week = ['天', '一', '二', '三', '四', '五', '六']; for(var i in obj) { fmt = fmt.replace(new RegExp(i+'+', 'g'), function(m) { var val = obj[i] + ''; if(i == 'w') return (m.length > 2 ? '星期' : '周') + week[val]; for(var j = 0, len = val.length; j < m.length - len; j++) val = '0' + val; return m.length == 1 ? val : val.substring(val.length - m.length); }); } return fmt; }, /** * 将字符串解析成日期 * @param str 输入的日期字符串,如'2014-09-13' * @param fmt 字符串格式,默认'yyyy-MM-dd',支持如下:y、M、d、H、m、s、S,不支持w和q * @returns 解析后的Date类型日期 */ parseDate: function(str, fmt) { fmt = fmt || 'yyyy-MM-dd'; var obj = {y: 0, M: 1, d: 0, H: 0, h: 0, m: 0, s: 0, S: 0}; fmt.replace(/([^yMdHmsS]*?)(([yMdHmsS])\3*)([^yMdHmsS]*?)/g, function(m, $1, $2, $3, $4, idx, old) { str = str.replace(new RegExp($1+'(\\d{'+$2.length+'})'+$4), function(_m, _$1) { obj[$3] = parseInt(_$1); return ''; }); return ''; }); obj.M--; // 月份是从0开始的,所以要减去1 var date = new Date(obj.y, obj.M, obj.d, obj.H, obj.m, obj.s); if(obj.S !== 0) date.setMilliseconds(obj.S); // 如果设置了毫秒 return date; }, /** * 将一个日期格式化成友好格式,比如,1分钟以内的返回“刚刚”, * 当天的返回时分,当年的返回月日,否则,返回年月日 * @param {Object} date */ formatDateToFriendly: function(date) { date = date || new Date(); date = typeof date === 'number' ? new Date(date) : date; var now = new Date(); if((now.getTime() - date.getTime()) < 60*1000) return '刚刚'; // 1分钟以内视作“刚刚” var temp = this.formatDate(date, 'yyyy年M月d'); if(temp == this.formatDate(now, 'yyyy年M月d')) return this.formatDate(date, 'HH:mm'); if(date.getFullYear() == now.getFullYear()) return this.formatDate(date, 'M月d日'); return temp; }, /** * 将一段时长转换成友好格式,如: * 147->“2分27秒” * 1581->“26分21秒” * 15818->“4小时24分” * @param {Object} second */ formatDurationToFriendly: function(second) { if(second < 60) return second + '秒'; else if(second < 60*60) return (second-second%60)/60+'分'+second%60+'秒'; else if(second < 60*60*24) return (second-second%3600)/60/60+'小时'+Math.round(second%3600/60)+'分'; return (second/60/60/24).toFixed(1)+'天'; }, /** * 将时间转换成MM:SS形式 */ formatTimeToFriendly: function(second) { var m = Math.floor(second / 60); m = m < 10 ? ( '0' + m ) : m; var s = second % 60; s = s < 10 ? ( '0' + s ) : s; return m + ':' + s; }, /** * 判断某一年是否是闰年 * @param year 可以是一个date类型,也可以是一个int类型的年份,不传默认当前时间 */ isLeapYear: function(year) { if(year === undefined) year = new Date(); if(year instanceof Date) year = year.getFullYear(); return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0); }, /** * 获取某一年某一月的总天数,没有任何参数时获取当前月份的 * 方式一:$.getMonthDays(); * 方式二:$.getMonthDays(new Date()); * 方式三:$.getMonthDays(2013, 12); */ getMonthDays: function(date, month) { var y, m; if(date == undefined) date = new Date(); if(date instanceof Date) { y = date.getFullYear(); m = date.getMonth(); } else if(typeof date == 'number') { y = date; m = month-1; } var days = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; // 非闰年的一年中每个月份的天数 //如果是闰年并且是2月 if(m == 1 && this.isLeapYear(y)) return days[m]+1; return days[m]; }, /** * 计算2日期之间的天数,用的是比较毫秒数的方法 * 传进来的日期要么是Date类型,要么是yyyy-MM-dd格式的字符串日期 * @param date1 日期一 * @param date2 日期二 */ countDays: function(date1, date2) { var fmt = 'yyyy-MM-dd'; // 将日期转换成字符串,转换的目的是去除“时、分、秒” if(date1 instanceof Date && date2 instanceof Date) { date1 = this.format(fmt, date1); date2 = this.format(fmt, date2); } if(typeof date1 === 'string' && typeof date2 === 'string') { date1 = this.parse(date1, fmt); date2 = this.parse(date2, fmt); return (date1.getTime() - date2.getTime()) / (1000*60*60*24); } else { console.error('参数格式无效!'); return 0; } } }); })(jQuery);
参考资料:https://www.cnblogs.com/liuxianan/p/js-date-format-parse.html