【分享】警惕你的 Date 对象
日子一天天过去,像时钟的表针一样摇曳着时光,很难想象没有时间的日子要怎样面对,又很讨厌生活在一分一秒的时间的格子里,人真是个矛盾的动物……
分分秒秒,我们都跟时间有密切的接触。也因此,很多程序中,也少不了对时间的处理。
这本来已经很复杂,可是,这么多的浏览器厂商还是没能给我们一个简单的环境。
还是那句话,生命不止,浏览器兼容性问题不歇。
今天,就说一下,跟时间有密切关系的
JS 内置对象 Date
Date对象在JS里应该是比较常用的对象了,属于Native Object(相对于 Host Object,即,宿主对象,例如,document)。
关于这个对象比较官方的说法在 ECMA-262 5th 的第 15.9 中,有兴趣的童鞋可以看看。
这个对象提供了好多比较实用的方法,但奈何有些方法在各浏览器中的实现是不同的。千里之堤,溃于蚁穴,往往一个小小的失误,会造成致命的问题。为了程序的健壮性,我们应该去认识这些差异性,以做到未雨绸缪,有效的规避这些错误。
那么,现在就说说常见的几个错误。
toLocaleString()的兼容性问题
根据 ECMA-262 5th中的说明,这个方法应该返回一个字符串的值,以合适的易读的方式,来显示当前时区的日期。具体没有规定显示成什么样子。
于是乎,差异就产生了。
看例子:
document.write((new Date("1999/09/09")).toLocaleString());
/*** date : Date 对象实例*/function localeDate(date) { return date.getFullYear()+ "年" + (date.getMonth()+ 1) + "月" + date.getDate() + "日" + " " + date.getHours() + ":" + date.getMinutes() + ":" + date.getSeconds();}
<div id="show"></div><script language="JavaScript"> window.onload = function() { var dateArray = [ "0000", "0001", "0099", "0100", "0500", "0999", "1000", "1001", "1500", "1899", "1900", "1901", "1999", "2000", "2001", "2009"]; var i = 0; for (i = 0; i < dateArray.length; i++) { var msg = ""; var date = new Date("Jan 01, " + dateArray[i] + " 01:00:00"); msg = dateArray[i] + ": " + "getYear(): " + date.getYear() + "; " + "getFullYear(): " + date.getFullYear(); showMsg(msg); } } function showMsg(msg) { document.getElementById('show').innerHTML += msg + "</br>"; }</script>
1001: getYear(): -899; getFullYear(): 1001
1500: getYear(): -400; getFullYear(): 1500
1899: getYear(): -1; getFullYear(): 1899
1900: getYear(): 0; getFullYear(): 1900
1901: getYear(): 1; getFullYear(): 1901
1999: getYear(): 99; getFullYear(): 1999
2000: getYear(): 100; getFullYear(): 2000
2001: getYear(): 101; getFullYear(): 2001
2009: getYear(): 109; getFullYear(): 2009
IE:
0000: getYear(): NaN; getFullYear(): NaN
0001: getYear(): NaN; getFullYear(): NaN
0099: getYear(): 99; getFullYear(): 1999
0100: getYear(): 100; getFullYear(): 100
0500: getYear(): 500; getFullYear(): 500
0999: getYear(): 999; getFullYear(): 999
1000: getYear(): 1000; getFullYear(): 1000
1001: getYear(): 1001; getFullYear(): 1001
1500: getYear(): 1500; getFullYear(): 1500
1899: getYear(): 1899; getFullYear(): 1899
1900: getYear(): 0; getFullYear(): 1900
1901: getYear(): 1; getFullYear(): 1901
1999: getYear(): 99; getFullYear(): 1999
2000: getYear(): 2000; getFullYear(): 2000
2001: getYear(): 2001; getFullYear(): 2001
2009: getYear(): 2009; getFullYear(): 2009
Chrome:
0000: getYear(): 100; getFullYear(): 2000
0001: getYear(): 101; getFullYear(): 2001
0099: getYear(): 99; getFullYear(): 1999
0100: getYear(): -1800; getFullYear(): 100
0500: getYear(): -1400; getFullYear(): 500
0999: getYear(): -901; getFullYear(): 999
1000: getYear(): -900; getFullYear(): 1000
1001: getYear(): -899; getFullYear(): 1001
1500: getYear(): -400; getFullYear(): 1500
1899: getYear(): -1; getFullYear(): 1899
1900: getYear(): 0; getFullYear(): 1900
1901: getYear(): 1; getFullYear(): 1901
1999: getYear(): 99; getFullYear(): 1999
2000: getYear(): 100; getFullYear(): 2000
2001: getYear(): 101; getFullYear(): 2001
2009: getYear(): 109; getFullYear(): 2009
Safari:
0000: getYear(): 100; getFullYear(): 2000
0001: getYear(): 101; getFullYear(): 2001
0099: getYear(): 99; getFullYear(): 1999
0100: getYear(): -1801; getFullYear(): 99
0500: getYear(): -1401; getFullYear(): 499
0999: getYear(): -902; getFullYear(): 998
1000: getYear(): -901; getFullYear(): 999
1001: getYear(): -899; getFullYear(): 1001
1500: getYear(): -400; getFullYear(): 1500
1899: getYear(): -1; getFullYear(): 1899
1900: getYear(): 0; getFullYear(): 1900
1901: getYear(): 1; getFullYear(): 1901
1999: getYear(): 99; getFullYear(): 1999
2000: getYear(): 100; getFullYear(): 2000
2001: getYear(): 101; getFullYear(): 2001
2009: getYear(): 109; getFullYear(): 2009
可见,在获取 1000 年后的日期的年份儿时,getFullYear() 方法还是比较保险的,但是,1000年以及以前的就不保险了。Safari对 100~1000年之间的年份儿,直接少了1年。其他浏览器倒还可以。小于100年的就比较扯了,都很扯。
更多兼容性问题,见:【分享】浏览器兼容性问题目录
[解决办法]
这种问题很好解决,就是不管它。
它既然天生这样,咱们费了老大力气去管它,它给开工资吗?
所以,它怎样,就让它怎样,由用户去发现然后选择是否使用它们。
这些浏览器,既然不能让咱们痛快,咱们也可以不管它,让它承受应有的后果,看不痛快的最后是谁。
[解决办法]
new Date() “不靠谱”的日期时,用数字参数靠谱一点。比如 'new Date(-2342342342342333)',或者给一个既有的 Date 对象用 'setFullYear()'。
引用:“Date 对象能够表示的日期范围约等于 1970 年 1 月 1 日前后各 285,616 年。”