一文掌握new?Date()?方法
大家平時(shí)在開發(fā)的時(shí)候有沒被new Date()折磨過?就是它的諸多怪異的設(shè)定讓你每每用的時(shí)候,都可能不小心踩坑。造成程序意外出錯(cuò),卻一下子找不到問題出處,那叫一個(gè)煩透了……下面,我就列舉它的“四宗罪”及應(yīng)用思考
可惡的四宗罪
1. Safari瀏覽器不兼容YYYY-MM-DD這樣的格式
new Date('2023-1-1');這行代碼無論在Macbook中還是iPhone中的Safari瀏覽器,返回的都是Invalid Date, Safari瀏覽器目前還理解不了YYYY-MM-DD這樣的格式,只支持YYYY/MM/DD。這就造成你在Windows環(huán)境下的代碼正常原型,而你的其他部分用戶異常顯示;
2、月份的索引是以0為起點(diǎn)的,而年份、日期卻不是
new Date(2023,1,1);
得到的是一個(gè)反直覺的結(jié)果:2023年2月1日?。。?/p>
Wed Feb 01 2023 00:00:00 GMT+0800 (中國(guó)標(biāo)準(zhǔn)時(shí)間)
同樣的,對(duì)應(yīng)的方法.setMonth()也是從0開始設(shè)置的。就……很無語!
3、年份小于100,默認(rèn)以19xx或20xx開頭
一般的應(yīng)用可能碰不到這樣的情況,畢竟現(xiàn)在是21世紀(jì)了,我們?cè)趹?yīng)用中看到的大部分時(shí)間都是現(xiàn)代的。但是當(dāng)你需要格式化公元元年-公元100年之間的時(shí)間,你就該懵了!
舉個(gè)栗子:
new Date(2023,1,1);
能正常返回時(shí)間對(duì)象
Wed Feb 01 2023 00:00:00 GMT+0800 (中國(guó)標(biāo)準(zhǔn)時(shí)間)
但是當(dāng)年份調(diào)到了東漢時(shí)期,公元50年2月1日
new Date(50,2,1);
恭喜你,你直接迎接了新中國(guó)!見證了歷史:
Wed Mar 01 1950 00:00:00 GMT+0800 (中國(guó)標(biāo)準(zhǔn)時(shí)間)
是的,Date直接幫你加了1900年的時(shí)間!如果需要獲得公元50年2月1日,得這么寫
new Date('0050-02-01');
返回:
Tue Feb 01 0050 08:05:43 GMT+0805 (中國(guó)標(biāo)準(zhǔn)時(shí)間)
請(qǐng)千萬不要嘗試添加時(shí)間,因?yàn)槟阌忠验_了……
new Date('0050-02-01 00:00:00');
返回:
Wed Feb 01 1950 00:00:00 GMT+0800 (中國(guó)標(biāo)準(zhǔn)時(shí)間)
你就說,它任性吧?!別氣餒,別忘了標(biāo)題還有20xx的情況
new Date('10-11-12');返回:
Thu Oct 11 2012 00:00:00 GMT+0800 (中國(guó)標(biāo)準(zhǔn)時(shí)間)
就是說,當(dāng)年份為2位數(shù)的時(shí)候,這種字符串格式的,構(gòu)造函數(shù)把最后面那個(gè)當(dāng)作年份,而且默認(rèn)它為20xx年
4、日期初始化不統(tǒng)一,存在時(shí)區(qū)差異
你相信嗎?'2018-01-01'和'2018/01/01'是不同的,存在一定時(shí)差
new Date('2018-01-01');
返回:
Mon Jan 01 2018 08:00:00 GMT+0800 (中國(guó)標(biāo)準(zhǔn)時(shí)間)
然而……
new Date('2018/01/01');
返回:
Mon Jan 01 2018 00:00:00 GMT+0800 (中國(guó)標(biāo)準(zhǔn)時(shí)間)
看到差異了嗎??jī)煞N格式返回的時(shí)間是不同的,查了個(gè)北京時(shí)間與格林尼治時(shí)間的時(shí)差,8個(gè)小時(shí)??!
應(yīng)用思考
在日常開發(fā)中,我們應(yīng)用new Date()無非就是對(duì)時(shí)間運(yùn)算及時(shí)間的格式化。
1. 時(shí)間的計(jì)算
需要方便對(duì)比兩個(gè)時(shí)間的早晚,可以分別對(duì)年份、月份、日期、小時(shí)等進(jìn)行單獨(dú)比較。而我們現(xiàn)有的操作還比較麻煩。
比如,我想知道2003年7月13日北京申奧成功到2008年8月8日北京奧運(yùn)開幕中間差了幾天,如何快速計(jì)算?這樣的計(jì)算在日常開發(fā)中還比較常見,特別是電商網(wǎng)站對(duì)搶購環(huán)節(jié)的倒計(jì)時(shí)。
還有諸如,當(dāng)前時(shí)間在100天以后又是幾月幾號(hào)呢?
2. 時(shí)間的比較
給定兩個(gè)時(shí)間,判斷哪個(gè)在前,哪個(gè)在后;給定一個(gè)時(shí)間返回,判斷某個(gè)時(shí)間是不是在這兩者之間。
3. 時(shí)間的格式化
在網(wǎng)站開發(fā)中,我們最常見的就是對(duì)后臺(tái)返回時(shí)間戳的格式化顯示。而原生帶來的僅有年份如何獲取,月份如何獲取,日期如何獲取的方法,就方便的無非就是toISOString()這樣的方法,但是返回的卻不一定是你要的格式。如何快速實(shí)現(xiàn)自定義格式化字符串,這也是一門技術(shù)。
困境的解決
想必大家日常中也用過 moment.js、dayjs、data-format這些工具吧?確實(shí)挺好用的,我也就順便說一下而已。因?yàn)槲乙_始打廣告了……面對(duì)著new Date()各種無語的坑,我慢慢的也弄了一個(gè)不大的庫(250行左右代碼)。
你要說我的庫和前面的幾個(gè)庫對(duì)比,有啥改進(jìn)的或者有啥特點(diǎn)的嗎?
??確實(shí)也沒有,我只是想用自己造的“輪子”,走自己路。它更符合我自己的使用習(xí)慣罷了
【項(xiàng)目開源地址】github.com/mumuy/datex
【項(xiàng)目演示地址】passer-by.com/datex/
提供的方法足以解決以上“四宗罪”及日常應(yīng)用。它提供多種初始化時(shí)間的方式:
實(shí)例化對(duì)象
// 通過時(shí)間戳
datex(123456789);
// 通過多個(gè)參數(shù)初始化
datex(2018,8,8);
// 通過時(shí)間字符串初始化
datex('2018-08-08');
datex('2018-04-04T16:00:00.000Z');
// 通過時(shí)間對(duì)象初始化
datex({year:2008,month:8,day:8,hour:8,minute:0,second:0});
// 通過時(shí)間數(shù)組初始化
datex([2018,8,8,8,8,0]);
// 無參數(shù)初始化
datex();時(shí)間戳及克隆
// 返回時(shí)間戳(毫秒) datex().getTime(); // 返回時(shí)間戳(秒) datex().getUnix(); // 克隆 datex().clone();
時(shí)間對(duì)象輸出
// 返回原生Date對(duì)象 datex().toDate(); // 返回時(shí)間字段對(duì)象 datex().toObject(); // 返回時(shí)間字段數(shù)組 datex().toArray(); // 返回字符串 datex().toString(); // 返回ISO字符串 datex().toISOString();
時(shí)間格式化
datex(123456789).format('YYYY-MM-DD');時(shí)間計(jì)算及比較
// 設(shè)置某字段值
datex(2022,10,1).set('year',2020).format();
// 增減某字段值,負(fù)值為減
datex(2022,10,1).change('year',1).format();
// 返回某字段值
datex().get('month');
// 獲取某字段起始時(shí)
// 例如:獲取這個(gè)月初是星期幾?
datex().startOf('month').format('W');
// 獲取某字段末尾時(shí)
// 例如:獲取這個(gè)月有多少天?(是不是很容易理解?end of month then get day!)
datex().endOf('month').get('day');
// 與某時(shí)間點(diǎn)差值
// 例如:北京2008年奧運(yùn)會(huì)開幕式過去多少天了?
datex().diffWith('2008-8-8','day');
// 是否在某個(gè)時(shí)間點(diǎn)之前
datex('2008-08-08').isBefore('2022-02-02');
// 是否在某個(gè)時(shí)間點(diǎn)之后
datex('2008-08-08').isAfter('2022-02-02');
// 是否和某個(gè)時(shí)間點(diǎn)相等
datex('2008-08-08').isSame('2018-02-02','year');
// 是否在兩個(gè)時(shí)間點(diǎn)之間
datex('2008-08-08').isBetween('2003-07-13','2022-02-02');有效性
datex('2008-13-12').isValid();ok, that is it. 你還遇到過哪些特別奇葩的問題,或者棘手的需求呢?不妨告訴我下,反正……??我也不一定會(huì)做。
到此這篇關(guān)于一文掌握new Date() 方法的文章就介紹到這了,更多相關(guān)new Date() 方法內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
js實(shí)現(xiàn)固定寬高滑動(dòng)輪播圖效果
本文主要分享了js實(shí)現(xiàn)PC固定寬高滑動(dòng)輪播圖效果的示例代碼。具有一定的參考價(jià)值,下面跟著小編一起來看下吧2017-01-01
javascript eval函數(shù)深入認(rèn)識(shí)
發(fā)現(xiàn)為本文起一個(gè)合適的標(biāo)題還不是那么容易,呵呵,所以在此先說明下本文的兩個(gè)目的2009-02-02
javascript實(shí)現(xiàn)的簡(jiǎn)單的表單驗(yàn)證
這篇文章主要介紹了javascript實(shí)現(xiàn)的簡(jiǎn)單的表單驗(yàn)證的相關(guān)資料,需要的朋友可以參考下2015-07-07
Bootstrap的Carousel配合dropload.js實(shí)現(xiàn)移動(dòng)端滑動(dòng)切換圖片
這篇文章主要介紹了bootstrap的Carousel配合dropload.js實(shí)現(xiàn)移動(dòng)端滑動(dòng)切換圖片,實(shí)現(xiàn)方法非常簡(jiǎn)單,具有參考借鑒價(jià)值,需要的朋友可以參考下2017-03-03
JavaScript實(shí)現(xiàn)班級(jí)抽簽小程序
這篇文章主要為大家詳細(xì)介紹了JavaScript實(shí)現(xiàn)班級(jí)抽簽小程序,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-05-05
淺談js的html元素的父節(jié)點(diǎn),子節(jié)點(diǎn)
下面小編就為大家?guī)硪黄獪\談js的html元素的父節(jié)點(diǎn),子節(jié)點(diǎn)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2016-08-08
JS實(shí)現(xiàn)頁面內(nèi)跳轉(zhuǎn)的簡(jiǎn)單代碼
這篇文章主要介紹了JS實(shí)現(xiàn)頁面內(nèi)跳轉(zhuǎn)的簡(jiǎn)單代碼,需要的朋友可以參考下2017-09-09

