Không tải lên, 100% cục bộ, không cần tài khoản

Bài viết

Unix timestamps và cron expressions giải thích

Unix timestamp chỉ là một số nguyên. Cron expression chỉ là năm trường. Cả hai xuất hiện liên tục trong công việc backend, và cả hai gây nhầm lẫn theo những cách có thể đoán trước: cái đầu vì múi giờ, cái sau vì đơn vị.

Unix timestamp là gì

Unix timestamp đếm số giây đã trôi qua kể từ 1970-01-01 00:00:00 UTC, một điểm tham chiếu được gọi là Unix epoch. Định nghĩa đó có hai hậu quả quan trọng. Thứ nhất, số đếm theo UTC: không có múi giờ nào được nhúng trong số đó. 1718400000 có nghĩa là cùng một khoảnh khắc ở khắp nơi trên Trái đất bất kể máy lưu trữ nó ở đâu. Thứ hai, epoch được định nghĩa theo giây, không phải đơn vị nào khác. Giá trị như 1718400000 luôn là giây kể từ nửa đêm 1 tháng 1 năm 1970 UTC, trừ khi một hệ thống hoặc giao thức đã thực hiện lựa chọn khác một cách tường minh. Timestamps được thiết kế không có múi giờ, chính xác là lý do tại sao chúng hữu ích cho logging, cơ sở dữ liệu, và giao tiếp giữa các hệ thống nơi đồng hồ ở các khu vực khác nhau phải đề cập đến cùng một khoảnh khắc một cách rõ ràng.

Dòng thời gian hiển thị Unix epoch tại 1970-01-01 00:00:00 UTC ở bên trái, timestamp hiện tại ở giữa, và ranh giới tràn 2038 ở bên phải, được đánh dấu với số nguyên có dấu 32-bit tối đa.

Giây, mili giây, và vấn đề năm 2038

Nhiều runtime và API hiện đại dùng mili giây thay vì giây. Date.now() của JavaScript trả về mili giây, vì vậy 1718400000000 là cùng khoảnh khắc với giá trị độ chính xác giây 1718400000. Khi bạn nhận được timestamp không quen thuộc, độ lớn cho bạn biết đơn vị: số 10 chữ số hầu như luôn là giây; số 13 chữ số hầu như luôn là mili giây. Vấn đề năm 2038 phát sinh từ một lựa chọn khác: lưu trữ timestamp độ chính xác giây trong số nguyên có dấu 32-bit. Giá trị tối đa của số nguyên có dấu 32-bit là 2147483647, tương ứng với 2038-01-19 03:14:07 UTC. Sau giây đó, bộ đếm tràn sang số âm lớn và ngày quay trở lại 1901 trên các hệ thống không xử lý ranh giới. Cách khắc phục là dùng lưu trữ 64-bit. Hầu hết hệ điều hành và cơ sở dữ liệu hiện tại đã làm như vậy, nhưng hệ thống nhúng, thiết bị mạng, và các định dạng file cũ đã cố định độ rộng trường từ hàng thập kỷ trước vẫn có nguy cơ.

Quy đổi epoch sang ngày người đọc được: bước múi giờ

Quy đổi giá trị epoch sang ngày có thể đọc cần hai bước: lấy các thành phần ngày UTC từ số nguyên, sau đó áp dụng lệch UTC để có giờ địa phương. Timestamp bản thân là UTC. Khi bạn hỏi ngày 1718325000 đại diện cho gì, câu trả lời đúng là 2024-06-14 lúc 00:30 theo UTC. Ở New York (UTC-4 vào mùa hè), cùng giây đó rơi vào tối hôm trước, 2024-06-13 lúc 20:30: ngày thay đổi, không chỉ giờ. Đây là bước tạo ra kết quả sai khi bỏ qua: một nhà phát triển log timestamp thô theo UTC, công cụ báo cáo hiển thị theo giờ địa phương mà không quy đổi, và ngày có vẻ lệch vài giờ hoặc cả ngày. Công cụ timestamp-converter trên Sunasty xử lý điều này một cách rõ ràng: bạn nhập giá trị epoch và nó hiển thị ngày giờ UTC cạnh ngày giờ địa phương của chính thiết bị bạn, để một lần vượt ranh giới ngày như thế này hiện rõ ngay lập tức. Quy đổi chạy hoàn toàn trong trình duyệt và không có gì bạn dán được gửi đi đâu.

Hai lưới lịch đặt cạnh nhau cho cùng một giá trị epoch: lưới UTC làm nổi bật một ngày theo lịch, còn lưới New York (UTC-4) làm nổi bật ngày trước đó, cho thấy ngày giờ địa phương lùi lại do chênh lệch múi giờ.

Cú pháp cron: năm trường, dải, bước, và danh sách

Cron expression lên lịch các công việc định kỳ trên các hệ thống giống Unix. Cú pháp tiêu chuẩn có năm trường cách nhau bằng dấu cách: phút (0-59), giờ (0-23), ngày trong tháng (1-31), tháng (1-12), ngày trong tuần (0-7, trong đó 0 và 7 đều đại diện cho Chủ nhật). Dấu sao (*) trong một trường có nghĩa là "mọi giá trị hợp lệ". Biểu thức 30 8 * * 1-5 chạy lúc 08:30 từ thứ Hai đến thứ Sáu. Dải dùng dấu gạch ngang: 1-5 bao gồm các giá trị 1, 2, 3, 4, 5. Danh sách dùng dấu phẩy: 1,15 có nghĩa là ngày 1 và 15. Bước dùng dấu gạch chéo: */15 trong trường phút có nghĩa là mỗi 15 phút (0, 15, 30, 45). Các tổ hợp này có thể xuất hiện cùng nhau: 0-30/10 có nghĩa là 0, 10, 20, 30. Một điều cron không có là trường múi giờ. Daemon đọc đồng hồ của máy nó chạy, được đặt theo múi giờ địa phương của máy chủ. Nếu máy chủ chạy UTC nhưng nhà phát triển mong đợi giờ địa phương, lịch kích hoạt vào giờ đồng hồ sai. Quy tắc thực tế là coi lịch cron là biểu thức giờ-địa-phương-máy-chủ và ghi lại múi giờ của máy chủ cùng với dòng cron.

Sử dụng timestamp-converter cục bộ

Công cụ timestamp-converter trên Sunasty quy đổi theo cả hai hướng: epoch sang ngày người đọc được và ngày người đọc được trở lại epoch. Bạn có thể nhập giá trị độ chính xác giây hoặc độ chính xác mili giây; công cụ phát hiện đơn vị từ độ lớn. Công cụ hiển thị kết quả theo UTC và theo múi giờ địa phương của chính thiết bị bạn cạnh nhau, cùng với giá trị giây và mili giây thô sẵn sàng để sao chép. Một nút Now điền timestamp hiện tại chỉ trong một cú nhấp, cách nhanh để kiểm tra Unix time hiện tại mà không cần mở terminal. Không có bộ chọn múi giờ riêng: cột địa phương luôn phản ánh bất kỳ múi giờ nào trình duyệt của bạn đang đặt. Tất cả điều này chạy trong trình duyệt. Giá trị bạn dán vào trường được đọc bởi JavaScript phía client và không bao giờ rời khỏi thiết bị.

Công cụ trong bài viết này

Câu hỏi thường gặp

Tại sao JavaScript dùng mili giây thay vì giây?

Đối tượng Date của JavaScript được thiết kế để làm việc với độ chính xác dưới giây từ đầu, và mili giây cho độ phân giải gấp một nghìn lần so với giây mà không cần dấu thập phân. Sự đánh đổi là các giá trị lớn hơn, đó là lý do tại sao Date.now() tạo ra số 13 chữ số trong khi hầu hết timestamps phía server là 10 chữ số.

Mọi máy chủ chạy cron có cần ở UTC không?

Không, nhưng chạy máy chủ trên UTC là thực hành phổ biến chính xác vì nó loại bỏ sự mơ hồ. Khi máy chủ ở UTC, cron expression như 0 2 * * * có nghĩa là 02:00 UTC và thời gian đó ổn định quanh năm. Trên máy chủ ở múi giờ quan sát giờ tiết kiệm ánh sáng ban ngày, cùng công việc đó kích hoạt vào khoảnh khắc UTC khác vào mùa hè và mùa đông, và có thể kích hoạt hai lần hoặc bỏ qua một lần tại ranh giới thay đổi đồng hồ.

Loại lưu trữ an toàn cho timestamps sau năm 2038 là gì?

Số nguyên có dấu 64-bit giữ timestamps độ chính xác giây đến năm 292277026596, vượt xa bất kỳ mối lo thực tế nào. Hầu hết cơ sở dữ liệu hiện tại lưu trữ timestamps dưới dạng giá trị 64-bit theo mặc định. Nếu bạn đang làm việc với schema kế thừa hoặc định dạng file nhị phân dùng trường 32-bit, di chuyển sang lưu trữ 64-bit trước ranh giới 2038 là cách khắc phục đúng.