需求描述
日常開發中,經常會遇到以下對於時間(日期)的操作需求:
- 格式化時間為 ‘年-月-日’ 或者 '年-月-日 時:分:秒'
- 比較兩段時間的大小
- 獲取兩段時間(日期)中間的所有時間段(日期)
質疑
來自路人甲大佬的質疑
路人甲大佬: 為啥不用day.js或者moment.js這些現成的庫
來自作者弱弱的回應
現在最流行的day.js輕量庫以及moment.js都可以實現以上功能,但是moment.js有12kb大小,day.js僅僅2kb大小,為了時間資料的格式化引入day.js完全沒有問題,但是後兩個功能的實現需要引入moment.js,作者認為還不如自己寫一套。
功能實現
時間格式化的實現
此功能無非呼叫原生js的Date物件的 getFullYear() 、 getMonth() 、 getDate() 等方法獲取值之後的拼接,在這裡不做贅述
比較兩段時間的大小
- 笨辦法
之前作者開發中只碰到了比較兩段日期的先後順序作校驗,所以採取了以下本辦法
Demo 1 - 比較兩天大小(笨辦法)
const day1 = '2018-11-12'
const day2 = '2018-10-22'
function compareDate (day1, day2) {
const day1Num = parseInt((day1.split('-').join('')), 10)
const day2Num = parseInt((day2.split('-').join('')), 10)
const differenceCount = day2Num - day1Num
console.log(differenceCount) // -90
let result = differenceCount === 0 ?
'the same day' : differenceCount > 0 ?
'the day1 is earlier than the day2' :
'the day2 is earlier than the day1'
return result
}
console.log(compareDate(day1, day2)) // the day2 is earlier than the day1
複製程式碼
問題:這種方法雖然達到了比較兩個日期的大小,但是其中的差值是需要進一步處理的,不是很嚴謹,而且涉及要計算小時的差值,則完全沒有辦法使用
- 利用js原生Date物件的 getTime() 換算處理
Demo 1 - 比較兩天大小(利用換算成距 1970 年 1 月 1 日之間的毫秒數)
function newCompareDate (day1, day2) {
const day1Date = new Date(day1)
const day1Time = day1Date.getTime()
const day2Date = new Date(day2)
const day2Time = day2Date.getTime()
const differenceCount = day2Time - day1Time
console.log(differenceCount) // -1814400000
let result = differenceCount === 0 ?
'the same day' : differenceCount > 0 ?
'the day1 is earlier than the day2' :
'the day2 is earlier than the day1'
return result
}
console.log(newCompareDate(day1, day2)) // the day2 is earlier than the day1
複製程式碼
利用js提供的getTime()方法換算成“距 1970 年 1 月 1 日之間的毫秒數”然後進行差值計算,如果要得到小時數或者天數,則進行進一步計算即可
獲取兩段時間(日期)中間的所有時間段(日期)
- 利用getTime()方法進行遞增計算
demo 2
function getAllDateArr (begin, end) {
let arr = []
let beginArr = begin.split('-')
let endArr = end.split('-')
let beginDate = new Date()
beginDate.setUTCFullYear(parseInt(beginArr[0], 10), parseInt(beginArr[1], 10) - 1, parseInt(beginArr[2], 10))
let endDate = new Date()
endDate.setUTCFullYear(parseInt(endArr[0], 10), parseInt(endArr[1], 10) - 1, parseInt(endArr[2], 10))
let beginSec = db.getTime() - 24 * 60 * 60 * 1000
let endSec = de.getTime()
for (let i = beginSec; i < endSec; i++) {
i = i + 24 * 60 * 60 * 1000
// 使用day.js格式化日期
arr.push(dayjs(new Date(i)).format('YYYY-MM-DD'))
}
return arr
}
getAllDateArr('2018-11-12', '2018-12-12')
複製程式碼
結語
以上功能除了day.js之外,其他功能如果引入moment.js則差不多需要14kb記憶體大小,但自己實現不到20行程式碼則可以實現功能,所以依賴第三方庫有時候可以考慮自己手動實現。
小tips
作者在之前的一個國際專案中碰到一個問題:在國內前端處理好資料傳送到後端,後端儲存後如果在其他時區獲取使用此時間,會出現時間顯示的誤差,原因是因為前後端時區不統一的問題,當時的解決方案是前端解決,前端只要在儲存及顯示的時候,獲取本地的時區然後進行時間的換算即可。
BY--LucaLJX (LucaLJX的github)