今天在業(yè)務(wù)層面遇到一個問題,我們以往如果在mysql中有個字段的格式是datetime,我們需要這個字段做篩選項的話,會這么寫
if startTime != 0 {
db = db.Where("unix_timestamp(created_at) >= ?", startTime)
}
if endTime != 0 {
db = db.Where("unix_timestamp(created_at) <= ?", endTime)
}
可以看到我們其實是將數(shù)據(jù)庫中的該字段從datetime轉(zhuǎn)成了時間戳,然后和我們篩選的時間戳進(jìn)行比較
在mysql中時間格式的字段使用datetime格式本來就是考慮到了一些時間字段可能會有1970年之前的值,比如生日birthday這樣的,而我們今天遇到的問題就是
- mysql不接受負(fù)值的時間戳
- 即使字段格式為datetime,unix_timestamp(datetime)轉(zhuǎn)化成時間戳后,時間戳還是從1970年開始的

時間戳
圖中可以很明顯地看出,1970年之前的時間戳都是0,哪怕這個字段能夠記錄1800年之后的時間
這就使得當(dāng)我們的篩選項需要用到1970年之前的時間的時候,上面那段代碼將無法正常進(jìn)行篩選
通過查百度得知,如果想要在mysql中使用負(fù)值時間戳,可以用
DATE_ADD(FROM_UNIXTIME(0), INTERVAL 時間戳 SECOND)
來實現(xiàn),比如1800年1月1日早上8點

基準(zhǔn)時間戳
也就是說,用這種寫法,可以將時間戳,包括負(fù)值時間戳,轉(zhuǎn)化為mysql的datetime格式,然后我們就可以直接和字段值進(jìn)行比較辣
SELECT * FROM `表名` WHERE birthday <= DATE_ADD(FROM_UNIXTIME(0), INTERVAL 時間戳 SECOND);
在代碼中的寫法就要改成
if startTime != 0 {
db = db.Where("birthday >= DATE_ADD(FROM_UNIXTIME(0), INTERVAL ? SECOND)", startTime)
}
if endTime != 0 {
db = db.Where("birthday <= DATE_ADD(FROM_UNIXTIME(0), INTERVAL ? SECOND)", endTime)
}
實際執(zhí)行邏輯就變成將我們傳入的時間戳轉(zhuǎn)換為datetime格式,然后直接與字段值進(jìn)行比較
測試通過,蓋姆歐瓦