关于js日期对象二三事
学习日期对象date之前,先来理清一些知识。
一个月有多少天?一年有多少天?什么叫平年和闰年?平年和闰年的区别?时间的基准点(起点)从何时开始算起?new Date()初始化的格式?
OK,带着这些问题,我们一步步,循序渐进的进入date对象的世界。
一,平年和闰年
公历年份是整百或整千的(也就是年份末尾至少有2个0的),用年份除以400,如果能整除,就是闰年,不能整除就是平年,
公历其他的年份,用年份除以4,如果能整除,就是闰年,不能整除就是平年,
如1900年,1900÷400=4……300 就是平年,平年2月是28天。
2000年,2000÷400=5 就是闰年,闰年2月是29天。
2001年,2001÷4=500……1 就是平年
2004年,2004÷4=501 就是闰年
闰年2月只有29天 平年2月只有28天
上面这段话就说明每一年的2月不是28天就是29天,而其他月份,1,3,5,7,8,10,12共7个月都是31天,4,6,9,11共4个月都是30天。因此这么一算,一年不是365天,就是366天。每四年出现一次闰年。
因此,闰年就是31*7+29+30*4=366天,平年就是31*7+28+30*4=365天。
二,时间的起点
为什么时间要从1970年1月1日开始算起?先阅读两篇文章了解一下。第一篇和第二篇,读完之后,我们可以从中发现,最早出现的UNIX操作系统考虑到计算机产生的年代和应用的 时限综合取了1970年1月1日作为UNIX TIME的纪元时间(开始时间),至于时间回归的现象相信随着64为操作系统的产生逐渐得到解决,因为用64位操作系统可以表示到 292,277,026,596年12月4日15时30分08秒,相信我们的N代子孙,哪怕地球毁灭那天都不用愁不够用了,因为这个时间已经是千亿年以后 了。因此这个规矩就一直定下来了。我们以1970年1月1日为起点开始计算。
细心的可能会想到,时分秒又是多少呢?别急,我们在打印一下。
从上面可以看出返回的结果是1970年1月1日,8点开始算起。真的是这样吗?实际上时分秒是 0 点 0 分 0 秒 ,0点是时间纪元。
打印出来的时间是8点而非0点,原因是存在系统时间和本地时间的问题,其实系统时间依然是0点,只不过我的电脑时区设置为东8区,故打印的结果是8点。
因此,通过上面的分析与探索,我们可以得出以下结论:
时间的起点是1970年1月1日0时0分0秒,只不过在中国由于电脑时区设置,所以会显示打印结果为8点。
三:date初始化格式
new Date() 日期参数初始化
我们实验一下:
1)new Date('2014/5/1 00:00:00');
2) new Date('2014-5-1 00:00:00');
3) new Date(1325295549549); //直接将毫秒数传参 new Date(ms)
4) new Date(2014,4,1,00,00,00); //如果不加引号就在月份那减1,因为月份是从0开始的
5) new Date('2014,5,1');
6) new Date("May 1,2014 00:00:00");
7) new Date("May 1,2014");
上述几种方式都能返回正确设置的时间。但我们要注意一下第四种写法,第四种写法,不加引号时,第二个参数是指第几个月,比如你这里的 4 就是第4个月,实际上已经是5月了,因为月份是从0开始的。加引号时,就相当于格式化时间格式。
因此,在用第四种方法的时候要记得月是从0开始算起的。
var today = new Date(); //获取现在的时间
这样,我们每次刷新页面都能得到当前的时刻,也就是说是变化的。如果我们想让它自动随着时间显示当前的年月日,时分秒,我们就需要编写一个js函数了。
<body onload="showtime()" > <script language="javascript"> function showtime(){ var today=new Date(); var h=today.getHours(); var m=today.getMinutes(); var s=today.getSeconds(); m=checkTime(m); s=checkTime(s); document.getElementById('text').innerHTML=h+":"+m+":"+s; setTimeout('showtime()',200); //这个时间尽量小一点,因为为了精确 } function checkTime(i) { if (i<10) {i="0" + i} return i ; } </script> <div id="text"></div> </body>
四:常用方法
1. Date.now()
= > 返回自 1970-1-1 00:00:00 UTC (时间标准时间)至今所经过的毫秒数。
Date.now(); //1469166290095
2. Date.parse()
= > 解析一个表示日期的字符串,并返回从 1970-1-1 00:00:00 所经过的毫秒数。
Date.parse('Sun Dec 17 1995 03:24:00 GMT+0800 (CST)'); //819141840000
3. getFullYear()
= > 返回指定日期对象的年份
var today = new Date();
today.getFullYear(); // 2016
4. getMonth()
= > 返回指定日期对象的月份(0-11)
var today = new Date();
today.getMonth(); // 6
5. getDate()
= > 返回指定日期对象的月份中的第几天(1-31)
var today = new Date();
today.getDate(); // 22
6. getHours()
= > 返回指定日期对象的小时(0-23)
var today = new Date();
today.getHours(); // 14
7. getMinutes()
= > 返回指定日期对象的分钟(0-59)
var today = new Date();
today.getMinutes(); // 40
8. getSeconds()
= > 返回指定日期对象的秒数(0-59)
var today = new Date();
today.getSeconds(); // 40
五:累计运行
有这么一个需求,假如我从2014年5月1号加入了某个神秘的社团,一直到现在?问我加入这个社团一共有 多少年多少月多少日多少时分秒?
提出这么一个需求后,我们就得先分析解决这个需求的逻辑。OK,我们知道两个日期段之间的毫秒数肯定的准确的。然后可以一直精确得换算出多少天,时分秒等。然后再往上求呢?多少天转化为年和月,我们知道1年有可能有365天或366天,相应的月份有28|29|30|31天,这样做是不是觉得要考虑的情况挺复杂。这种思路肯定是不太好处理的。这时,我们需要换一种思路。等价处理法。
如何等价?因为我们可以明确的知道两个时间段之间的毫秒数,而我们又知道基准时间是从1970年1月1日0点开始算起的。因此我们可以将差值毫秒数传进new Date()作为它的参数,然后求出对应的时间日期,在对应着减去基准时间,因为基准时间都是最小的。所以不会出现值为负数,然后像高位借1的情况。
var today = new Date();
var oldtime = new Date("2014/5/1 00:00:00");
得到这两者之后,我们还需要考虑的一点是 getTime()
var cha = today - oldtime; //这个就相当于today.getTime() - oldtime.getTime(),隐式转换了
getTime()是获取dateObject 指定的日期和时间距 1970 年 1 月 1 日午夜(GMT 时间)之间的毫秒数。
什么是午夜,也就是夜里12点钟,这里取得是距离1月1日夜里12点,也就是1月2日0点开始的,因此,我们计算差值的时候,最后不包括1月1日这一天,就是这么来的。哈哈。
讲道理,我们从字面上来看,午夜应该就是夜里12点,但是系统时间,我们看到new Date(0)获取的却是从1月1日0点开始的,因此这里有点迷惑。如果有明白的小伙伴可以告诉一下。
再来考虑一个问题,由于我们计时都是从0点开始,这符合我们的逻辑,但是当我们在电脑上输出new Date(0); 发现出来的居然是08:00:00,这是因为我们处于东8区,默认8点开始的。因此我们再计算毫秒数差值的时候要讲8*3600*1000这个毫秒数剪掉才是对应的我们真正的时间。
var DTIME = 8*3600*1000;
因此,理清这个逻辑后我们就会很容器理解了。
两个时间段的差值为
var cha = today - oldtime - DTIME;
将这段差值传进new Date()中。
var t = new Date(cha);
然后求出对应的年月日,时分秒。
END!!