時間戳(Unix Timestamp)以秒為單位記錄自 1970-01-01 00:00:00 UTC 經過的秒數,便於跨時區存儲、計算與排序。MySQL 提供 UNIX_TIMESTAMP() 與 FROM_UNIXTIME() 實現雙向轉換,本文詳解用法、格式化輸出與範圍限制。
-- 當前時間戳
SELECT UNIX_TIMESTAMP();
-- 1436775578
-- 指定日期時間轉換
SELECT UNIX_TIMESTAMP('2015-07-13 16:20:20');
-- 1436775620
-- 日期類型列轉換
SELECT UNIX_TIMESTAMP(create_time) FROM orders;
注意:參數支持 DATE、DATETIME、TIMESTAMP、字符串格式 'YYYY-MM-DD HH:MM:SS'。
-- 默認格式 YYYY-MM-DD HH:MM:SS
SELECT FROM_UNIXTIME(1436775620);
-- 2015-07-13 16:20:20
-- 自定義格式輸出
SELECT FROM_UNIXTIME(1436775620, '%Y-%m-%d');
-- 2015-07-13
SELECT FROM_UNIXTIME(1436775620, '%Y年%m月%d日 %H:%i:%s');
-- 2015年07月13日 16:20:20
常用格式符:%Y年、%m月、%d日、%H時(24h)、%i分、%s秒、%W星期名、%w星期(0-6)。
TIMESTAMP 類型範圍:1970-01-01 00:00:01 UTC ~ 2038-01-19 03:14:07 UTC(32 位有符號整數上限)。
SELECT FROM_UNIXTIME(0);
-- 1970-01-01 08:00:00 (北京時區 UTC+8)
SELECT FROM_UNIXTIME(2147483647);
-- 2038-01-19 11:14:07 (北京時區)
SELECT FROM_UNIXTIME(2147483648);
-- NULL (溢出)
解決方案:需存儲 2038 年後日期,請使用 DATETIME(範圍 1000-01-01 ~ 9999-12-31)或 BIGINT 存儲毫秒級時間戳。
<?php
// 時間戳 -> 日期
echo date('Y-m-d H:i:s', 1156219870); // 2006-06-21 18:31:10
// 日期 -> 時間戳
echo strtotime('2010-03-24 08:15:42'); // 1269399342
// strtotime 相對時間
echo strtotime('+1 day'); // 明天這時的時間戳
echo strtotime('next Monday'); // 下周一
// mktime 組裝日期
echo mktime(21, 50, 55, 7, 14, 2010); // 1279115455
// 自動修正越界日期
echo date('Y-m-d', mktime(0, 0, 0, 12, 32, 2007)); // 2008-01-01
// 下月最後一天技巧
$lastday = mktime(0, 0, 0, 3, 0, 2008);
echo date('Y-m-d', $lastday); // 2008-02-29 (閏年)
?>
-- 查詢最近 7 天訂單
SELECT * FROM orders
WHERE create_time >= FROM_UNIXTIME(UNIX_TIMESTAMP() - 7*24*3600);
-- 按天分組統計(利用 DATE 函數)
SELECT DATE(FROM_UNIXTIME(create_time)) AS day, COUNT(*)
FROM orders
GROUP BY day;
-- 跨時區應用:存儲 UTC 時間戳,顯示時轉換為用戶時區
SELECT FROM_UNIXTIME(create_time + 8*3600) AS beijing_time FROM orders;
| 函數 | 輸入 | 輸出 | 典型用途 |
|---|---|---|---|
| UNIX_TIMESTAMP() | 日期/字符串/無 | 整數秒數 | 存儲、比較、排序、分區 |
| FROM_UNIXTIME() | 整數秒數 | 日期字符串 | 顯示、報表、導出 |