核心 SQL
SELECT UNIX_TIMESTAMP(ADDDATE(NOW(), INTERVAL -60 DAY));
函數鏈解析
NOW():獲取當前日期時間(YYYY-MM-DD HH:MM:SS 格式)
ADDDATE(date, INTERVAL expr unit):日期加減運算
INTERVAL -60 DAY 表示向前推 60 天
- 等價寫法:
DATE_SUB(NOW(), INTERVAL 60 DAY) 或 NOW() - INTERVAL 60 DAY
UNIX_TIMESTAMP(datetime):將日期時間轉換為 Unix 時間戳(秒數)
常用變體
| 需求 | SQL | 說明 |
| N 天前 00:00:00 | UNIX_TIMESTAMP(DATE_SUB(DATE(NOW()), INTERVAL 60 DAY)) | DATE() 截取日期部分,時間歸零 |
| N 天前 23:59:59 | UNIX_TIMESTAMP(DATE_ADD(DATE(NOW()), INTERVAL -59 DAY)) + 86399 | 當天最後一秒 |
| N 小時前 | UNIX_TIMESTAMP(DATE_SUB(NOW(), INTERVAL 6 HOUR)) | 單位改為 HOUR |
| N 分鐘前 | UNIX_TIMESTAMP(DATE_SUB(NOW(), INTERVAL 30 MINUTE)) | 單位改為 MINUTE |
| 本月月初 | UNIX_TIMESTAMP(DATE_FORMAT(NOW(), '%Y-%m-01')) | 格式化拼接 |
| 上月同日 | UNIX_TIMESTAMP(DATE_SUB(NOW(), INTERVAL 1 MONTH)) | MONTH 間隔自動處理月份天數差異 |
應用場景示例
刪除 60 天前的歷史數據
DELETE FROM access_log
WHERE create_time < UNIX_TIMESTAMP(ADDDATE(NOW(), INTERVAL -60 DAY));
分區表按天清理
ALTER TABLE sales DROP PARTITION p_202301;
應用層配合(PHP 示例)
$sixtyDaysAgo = strtotime('-60 days');
// 或直接用 SQL 計算,避免應用層時區差異
$sql = "SELECT * FROM orders
WHERE created_at > UNIX_TIMESTAMP(ADDDATE(NOW(), INTERVAL -60 DAY))";
時區陷阱提示
NOW() 返回會話時區時間,受 time_zone 系統變量影響
- Unix 時間戳本質是 UTC 秒數,
UNIX_TIMESTAMP() 會按會話時區轉換
- 跨時區應用建議:統一會話時區為 UTC(
SET time_zone = '+00:00'),或在應用層用 UTC 計算後傳參
最佳實踐: 將時間邏輯下推到 SQL 層,利用 MySQL 日期函數處理時區與閏年/月份天數差異,減少應用層 Bug。