這里給大家分享我在網上總結出來的一些知識,希望對大家有所幫助
大家平時在開發的時候有沒被new Date()折磨過?就是它的諸多怪異的設定讓你每每用的時候,都可能不小心踩坑,造成程式意外出錯,卻一下子找不到問題出處,那叫一個煩透了…… 下面,我就列舉它的“四宗罪”及應用思考
可惡的四宗罪
1. Safari瀏覽器不兼容YYYY-MM-DD這樣的格式
new Date('2023-1-1');
這行代碼無論在Macbook中還是iPhone中的Safari瀏覽器,回傳的都是Invalid Date, Safari瀏覽器目前還理解不了YYYY-MM-DD這樣的格式,只支持YYYY/MM/DD,這就造成你在Windows環境下的代碼正常原型,而你的其他部分用戶例外顯示;
2、月份的索引是以0為起點的,而年份、日期卻不是
new Date(2023,1,1);
得到的是一個反直覺的結果:2023年2月1日!!!
Wed Feb 01 2023 00:00:00 GMT+0800 (中國標準時間)
同樣的,對應的方法.setMonth()也是從0開始設定的,就……很無語!
3、年份小于100,默認以19xx或20xx開頭
一般的應用可能碰不到這樣的情況,畢竟現在是21世紀了,我們在應用中看到的大部分時間都是現代的,但是當你需要格式化公元元年-公元100年之間的時間,你就該懵了!
舉個栗子:
new Date(2023,1,1);
能正常回傳時間物件
Wed Feb 01 2023 00:00:00 GMT+0800 (中國標準時間)
但是當年份調到了東漢時期,公元50年2月1日
new Date(50,2,1);
恭喜你,你直接迎接了新中國!見證了歷史:
Wed Mar 01 1950 00:00:00 GMT+0800 (中國標準時間)
是的,Date直接幫你加了1900年的時間!如果需要獲得公元50年2月1日,得這么寫
new Date('0050-02-01');
回傳:
Tue Feb 01 0050 08:05:43 GMT+0805 (中國標準時間)
請千萬不要嘗試添加時間,因為你又要裂開了……
new Date('0050-02-01 00:00:00');
回傳:
Wed Feb 01 1950 00:00:00 GMT+0800 (中國標準時間)
你就說,它任性吧?!別氣餒,別忘了標題還有20xx的情況
new Date('10-11-12');
回傳:
Thu Oct 11 2012 00:00:00 GMT+0800 (中國標準時間)
就是說,當年份為2位數的時候,這種字串格式的,建構式把最后面那個當作年份,而且默認它為20xx年
4、日期初始化不統一,存在時區差異
你相信嗎?'2018-01-01'和'2018/01/01'是不同的,存在一定時差
new Date('2018-01-01');
回傳:
Mon Jan 01 2018 08:00:00 GMT+0800 (中國標準時間)
然而……
new Date('2018/01/01');
回傳:
Mon Jan 01 2018 00:00:00 GMT+0800 (中國標準時間)
看到差異了嗎?兩種格式回傳的時間是不同的,查了個北京時間與格林尼治時間的時差,8個小時啊!
應用思考
在日常開發中,我們應用new Date()無非就是對時間運算及時間的格式化,
1. 時間的計算
需要方便對比兩個時間的早晚,可以分別對年份、月份、日期、小時等進行單獨比較,而我們現有的操作還比較麻煩,
比如,我想知道2003年7月13日北京申奧成功到2008年8月8日北京奧運開幕中間差了幾天,如何快速計算?這樣的計算在日常開發中還比較常見,特別是電商網站對搶購環節的倒計時,
還有諸如,當前時間在100天以后又是幾月幾號呢?
2. 時間的比較
給定兩個時間,判斷哪個在前,哪個在后;給定一個時間回傳,判斷某個時間是不是在這兩者之間,
3. 時間的格式化
在網站開發中,我們最常見的就是對后臺回傳時間戳的格式化顯示,而原生帶來的僅有年份如何獲取,月份如何獲取,日期如何獲取的方法,就方便的無非就是toISOString()這樣的方法,但是回傳的卻不一定是你要的格式,如何快速實作自定義格式化字串,這也是一門技術,
困境的解決
想必大家日常中也用過 moment.js、dayjs、data-format這些工具吧?確實挺好用的,我也就順便說一下而已,因為我要開始打廣告了……面對著new Date()各種無語的坑,我慢慢的也弄了一個不大的庫(250行左右代碼),
你要說我的庫和前面的幾個庫對比,有啥改進的或者有啥特點的嗎?
??確實也沒有,我只是想用自己造的“輪子”,走自己路,它更符合我自己的使用習慣罷了
【專案開源地址】github.com/mumuy/datex
【專案演示地址】passer-by.com/datex/
提供的方法足以解決以上“四宗罪”及日常應用,它提供多種初始化時間的方式:
實體化物件
// 通過時間戳 datex(123456789); // 通過多個引數初始化 datex(2018,8,8); // 通過時間字串初始化 datex('2018-08-08'); datex('2018-04-04T16:00:00.000Z'); // 通過時間物件初始化 datex({year:2008,month:8,day:8,hour:8,minute:0,second:0}); // 通過時間陣列初始化 datex([2018,8,8,8,8,0]); // 無引數初始化 datex();
時間戳及克隆
// 回傳時間戳(毫秒) datex().getTime(); // 回傳時間戳(秒) datex().getUnix(); // 克隆 datex().clone();
時間物件輸出
// 回傳原生Date物件 datex().toDate(); // 回傳時間欄位物件 datex().toObject(); // 回傳時間欄位陣列 datex().toArray(); // 回傳字串 datex().toString(); // 回傳ISO字串 datex().toISOString();
時間格式化
datex(123456789).format('YYYY-MM-DD');
時間計算及比較
// 設定某欄位值 datex(2022,10,1).set('year',2020).format(); // 增減某欄位值,負值為減 datex(2022,10,1).change('year',1).format(); // 回傳某欄位值 datex().get('month'); // 獲取某欄位起始時 // 例如:獲取這個月初是星期幾? datex().startOf('month').format('W'); // 獲取某欄位末尾時 // 例如:獲取這個月有多少天?(是不是很容易理解?end of month then get day!) datex().endOf('month').get('day'); // 與某時間點差值 // 例如:北京2008年奧運會開幕式過去多少天了? datex().diffWith('2008-8-8','day'); // 是否在某個時間點之前 datex('2008-08-08').isBefore('2022-02-02'); // 是否在某個時間點之后 datex('2008-08-08').isAfter('2022-02-02'); // 是否和某個時間點相等 datex('2008-08-08').isSame('2018-02-02','year'); // 是否在兩個時間點之間 datex('2008-08-08').isBetween('2003-07-13','2022-02-02');
有效性
datex('2008-13-12').isValid();
本文轉載于:
https://juejin.cn/post/7221884988492382267
如果對您有所幫助,歡迎您點個關注,我會定時更新技術檔案,大家一起討論學習,一起進步,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/550585.html
標籤:其他