Thời gian Unix đơn giản chỉ là cách ghi lại thời gian bằng số giây (đôi khi là mili giây) đã trôi qua kể từ nửa đêm ngày 1 tháng 1 năm 1970 theo UTC. Định dạng này siêu phổ biến trong lập trình: lưu trữ dễ, truyền đi dễ, so sánh cũng dễ vì nó chỉ là một con số thôi mà.
Nói đơn giản, thời gian Unix giống như một cái đồng hồ bấm giờ bắt đầu chạy từ năm 1970 và không bao giờ dừng lại. Thấy một con số lạ kiểu 1697222400 chưa? Đừng hoảng — đó chỉ là số giây đã trôi qua từ lúc bắt đầu thôi. Muốn biết nó là ngày nào? Sắp tới mình sẽ chỉ cách tính nhé!
Định dạng này thường được dùng khi đồng bộ dữ liệu giữa các hệ thống, lưu dấu thời gian (timestamp) và khi cần so sánh nhanh xem cái nào xảy ra trước, cái nào sau.
Chuyển đổi sang thời gian Unix
Trong PostgreSQL có hàm đặc biệt EXTRACT(EPOCH FROM ...), giúp chuyển đổi ngày hoặc timestamp sang thời gian Unix.
Làm thử chuyển ngày hiện tại sang định dạng này nhé:
SELECT EXTRACT(EPOCH FROM NOW());
Kết quả sẽ kiểu như này:
1697222400
Kết quả này chỉ là ngày giờ hiện tại tính bằng giây kể từ năm 1970 thôi.
Còn đây là cách chuyển một ngày cố định:
SELECT EXTRACT(EPOCH FROM TIMESTAMP '2023-10-01 12:00:00');
Kết quả:
1696152000
Bây giờ mình biết ngày 1 tháng 10 năm 2023 lúc 12:00 UTC tương ứng với giá trị này.
Chuyển đổi từ thời gian Unix
Tất nhiên là có hàm chuyển ngược lại rồi. Nếu bạn có thời gian Unix và muốn chuyển nó về định dạng dễ đọc cho người, dùng hàm TO_TIMESTAMP() là chuẩn bài.
Làm thử chuyển thời gian Unix sang ngày giờ nhé
SELECT TO_TIMESTAMP(1697222400);
Kết quả:
2023-10-13 00:00:00+00
Bây giờ mình thấy đây là ngày 13 tháng 10 năm 2023 lúc 00:00 theo UTC.
Ứng dụng thực tế của thời gian Unix
Giả sử bạn có bảng events, nơi lưu thông tin về các sự kiện, bao gồm cả timestamp ở định dạng thời gian Unix.
CREATE TABLE events (
id SERIAL PRIMARY KEY,
event_name TEXT,
event_time BIGINT -- để lưu thời gian Unix
);
Mình có thể chèn dữ liệu vào bảng này, chỉ cần đưa timestamp ở định dạng thời gian Unix:
INSERT INTO events (event_name, event_time)
VALUES
('Khoi dong server', 1697222400),
('Cap nhat co so du lieu', 1697308800);
Để chuyển thông tin này sang dạng dễ đọc, chỉ cần dùng TO_TIMESTAMP:
SELECT event_name, TO_TIMESTAMP(event_time) AS readable_time
FROM events;
Kết quả:
| event_name | readable_time |
|---|---|
| Khoi dong server | 2023-10-13 00:00:00+00 |
| Cap nhat co so du lieu | 2023-10-14 00:00:00+00 |
Mẹo và lỗi thường gặp
- Chọn sai độ chính xác
Nếu thời gian Unix của bạn là mili giây (ví dụ 1697222400000), không thể truyền trực tiếp vào hàm TO_TIMESTAMP hoặc dùng trong EXTRACT được đâu. Phải chia giá trị cho 1000 nhé:
SELECT TO_TIMESTAMP(1697222400000 / 1000);
Kết quả:
2023-10-13 00:00:00+00
- Bỏ qua múi giờ
Thời gian Unix luôn ở UTC, nên kết quả sẽ không tính đến múi giờ đâu, trừ khi bạn chuyển đổi thủ công. Ví dụ:
SELECT TO_TIMESTAMP(1697222400) AT TIME ZONE 'Europe/Moscow';
Kết quả:
2023-10-13 03:00:00
- Vấn đề với số quá lớn
Đôi khi dev lỡ truyền giá trị thời gian Unix quá lớn (kiểu mili giây thay vì giây). Kết quả sẽ sai bét luôn:
SELECT TO_TIMESTAMP(1697222400000); -- Se bi loi!
Muốn sửa thì phải chia đúng cho 1000 nhé.
Ví dụ: tính thời gian hoàn thành task
Lấy ví dụ thực tế: bạn có bảng task tasks, và muốn tính xem đã bao lâu kể từ khi tạo mỗi task.
Tạo bảng:
CREATE TABLE tasks (
id SERIAL PRIMARY KEY,
task_name TEXT,
created_at TIMESTAMP DEFAULT NOW()
);
Thêm vài task:
INSERT INTO tasks (task_name)
VALUES
('Task 1'),
('Task 2'),
('Task 3');
Bây giờ mình có thể thêm cột thời gian Unix:
SELECT id, task_name, EXTRACT(EPOCH FROM created_at) AS created_epoch
FROM tasks;
Kết quả:
| id | task_name | created_epoch |
|---|---|---|
| 1 | Task 1 | 1697222400 |
| 2 | Task 2 | 1697233200 |
Và tính xem đã bao lâu kể từ khi tạo (tính bằng giây):
SELECT id, task_name, EXTRACT(EPOCH FROM NOW()) - EXTRACT(EPOCH FROM created_at) AS elapsed_seconds
FROM tasks;
Kết quả:
| id | task_name | elapsed_seconds |
|---|---|---|
| 1 | Task 1 | 3600 |
| 2 | Task 2 | 7200 |
Khi nào và tại sao nên dùng thời gian Unix?
Thời gian Unix cực kỳ hợp để lưu trữ dữ liệu thời gian khi truyền giữa các hệ thống, so sánh timestamp và các tác vụ cần tiết kiệm tài nguyên CPU. Nó được dùng nhiều trong API, web dev, phân tích dữ liệu, cũng như đồng bộ giữa server và client. Nhưng nhớ lưu ý: nó luôn ở UTC, có thể là giây hoặc mili giây, và định dạng lưu trữ cũng khác nhau.
Nếu bạn cần tích hợp với hệ thống ngoài mà "nói chuyện bằng thời gian Unix", giờ bạn đã biết cách xử lý nó trong PostgreSQL rồi nhé. Cứ mạnh dạn dùng TO_TIMESTAMP và EXTRACT(EPOCH) để chuyển đổi qua lại, mọi vấn đề về thời gian sẽ được giải quyết ngon lành!
GO TO FULL VERSION