Khi cột lưu timestamp Unix (số giây từ 1970-01-01 UTC) kiểu BIGINT hoặc INT, MySQL dùng FROM_UNIXTIME() chuyển thành DATETIME, sau đó trích xuất tháng bằng MONTH().
Ví dụ minh họa
Tạo bảng:
mysql> CREATE TABLE DemoTable1457 (
Value BIGINT
);
Chèn timestamp (giây):
mysql> INSERT INTO DemoTable1457 VALUES (1570207117); -- 2019-10-04 mysql> INSERT INTO DemoTable1457 VALUES (1548947534); -- 2019-01-31 mysql> INSERT INTO DemoTable1457 VALUES (1575213134); -- 2019-12-01
Dữ liệu:
mysql> SELECT * FROM DemoTable1457;
+------------+ | Value | +------------+ | 1570207117 | | 1548947534 | | 1575213134 | +------------+
Chuyển timestamp → tháng
mysql> SELECT MONTH(FROM_UNIXTIME(Value))
FROM DemoTable1457;
Kết quả:
+-----------------------------+ | month(from_unixtime(Value)) | +-----------------------------+ | 10 | | 1 | | 12 | +-----------------------------+
Giải thích
FROM_UNIXTIME(Value): Chuyển số giây Unix →DATETIME(múi giờ session).MONTH(...): Trích xuất tháng (1-12) từ DATETIME.- Kết hợp:
MONTH(FROM_UNIXTIME(Value)).
Các trích xuất thành phần thời gian khác
| Thành phần | Hàm | Ví dụ kết quả |
|---|---|---|
| Năm | YEAR(FROM_UNIXTIME(Value)) | 2019 |
| Tháng | MONTH(FROM_UNIXTIME(Value)) | 10 |
| Ngày | DAY(FROM_UNIXTIME(Value)) | 4 |
| Giờ | HOUR(FROM_UNIXTIME(Value)) | 14 |
| Phút | MINUTE(FROM_UNIXTIME(Value)) | 30 |
| Giây | SECOND(FROM_UNIXTIME(Value)) | 17 |
| Ngày trong tuần | DAYOFWEEK(FROM_UNIXTIME(Value)) | 1 (CN) - 7 (T7) |
| Ngày trong năm | DAYOFYEAR(FROM_UNIXTIME(Value)) | 277 |
| Tuần trong năm | WEEK(FROM_UNIXTIME(Value)) | 40 |
| Quý | QUARTER(FROM_UNIXTIME(Value)) | 4 |
Định dạng tùy chỉnh (DATE_FORMAT)
SELECT DATE_FORMAT(FROM_UNIXTIME(Value), '%Y-%m-%d %H:%i:%s') AS FullDateTime,
DATE_FORMAT(FROM_UNIXTIME(Value), '%M %Y') AS MonthYear
FROM DemoTable1457;
⚠️ Lưu ý quan trọng
- Múi giờ:
FROM_UNIXTIMEdùng múi giờ của session (@@session.time_zone). Timestamp Unix luôn UTC. Kết quả tháng có thể khác nếu múi giờ session không phải UTC. - Timestamp milliseconds: Nếu giá trị là milliseconds (13 chữ số), chia 1000 trước:
FROM_UNIXTIME(Value/1000). - Index: Không thể index trực tiếp trên
MONTH(FROM_UNIXTIME(Value)). Cần virtual column + index (MySQL 5.7+) hoặc lưu thêm cột DATE/DATETIME riêng.
Best Practice
Nên lưu cột kiểu DATETIME hoặc TIMESTAMP thay vì BIGINT Unix timestamp — tận dụng index, hàm ngày tháng gốc, timezone handling tự động, và dễ đọc khi debug.