引言
前幾天開發中突然接到測試提的一個 Bug,說我的時間組件顯示異常。
我很詫異,這里初始化數據是后端返回的,我什么也沒改,這bug提給我干啥。我去問后端:“這數據是不是有問題?”。后端答:“沒問題啊,我們一直都是這么返回的時間戳,其他人用也沒報錯。”
于是,對比生產環境數據,我終于找到了問題根源:后端時間戳的類型,從 Number 靜悄悄地變成了 String。
Bug原因
問題的原因,肯定就出現在時間數據解析上了,代碼中,我統一用的dayjs做的時間解析。
如圖,對時間戳的解析我都是這么寫的
const time = dayjs(res.endTime).format('YYYY-MM-DD HH:mm:ss')
于是,我分別試了兩種數據類型的解析方式:
- 字符型
dayjs('175008959900').format('YYYY-MM-DD hh:mm:ss') // 1975-07-19 01:35:59
- 數值型
dayjs(Number('175008959900')).format('YYYY-MM-DD HH:mm:ss') // 2025-07-17 06:59:59
看來,問題原因顯而易見了:
由于后端返回的是字符串類型 的 '175008959900'
,dayjs()
在處理字符串時,會嘗試按“常見的日期字符串格式”進行解析(如 YYYY-MM-DD
、YYYYMMDD
等),并不會自動識別為時間戳。所以它不會把這個字符串當作毫秒時間戳來解析,而是直接失敗(解析成無效日期),但 dayjs 會退化為 Unix epoch(1970 年)或給出錯誤結果,最終導致返回的是錯誤的時間。
如何避免此類問題
同dayjs一樣,原生的 new Date()
在解析時間戳時也存在類似的問題,因此,不管是 Date
還是 dayjs
,一律對后端返回的時間戳 Number(input)
兜底處理,永遠不要信任它傳的是數字還是字符串:
const ts = Number(res.endTime);
const date = new Date(ts);
思考
其實出現這個問題,除了后端更改時間戳類型,也在于我沒有充分理解“時間戳”的含義。我一直以為時間戳就是一段字符或一段數字,因此,從來沒有想過做任何兜底處理。那么,什么是時間戳?
時間戳(Timestamp) 是一種用來表示時間的數字,通常表示從某個“起點時刻”到某個指定時間之間所經過的時間長度。這個“起點”大多數情況下是 1970 年 1 月 1 日 00:00:00 UTC(Unix 紀元)。
常見時間戳類型:
類型 | 單位 | 示例值 | 說明 |
---|---|---|---|
Unix 時間戳(秒) | 秒 | 1750089599 | 常見于后端接口、數據庫存儲 |
毫秒時間戳 | 毫秒 | 1750089599000 | JavaScript 常用,Date.now() |
時間戳的意義:
- 它是一個 絕對時間的數字化表示,可以跨語言、跨平臺統一理解;
- 更容易做計算:兩個時間戳相減就能得到毫秒差值(時間間隔);
- 更緊湊:比如比字符串
"2025-07-17 06:59:59"
更短,處理性能更高。
在 JavaScript 中的使用:
console.log(Date.now()); // 比如:1714729530000// 將時間戳轉為日期
console.log(new Date(1750089599000)); // Thu Jul 17 2025 06:59:59 GMT+0800
關于我
一個熱愛技術分享的資深前端工程師,技術棧為Vue、React、Threejs,當然對一些前沿的技術也比較感興趣,如微前端、鴻蒙開發、油猴腳本開發等。
如果你對前端技術也充滿熱愛或者希望關注一些前沿技術,歡迎加群討論~
當然,如果你有任何面試、工作上遇到的技術問題也都可以在群里提問,有時間我就會及時回答~