DevToolPal
VI

Biểu thức cron

Ngày cuối cùng của mỗi tháng

Cron chuẩn không có ký hiệu "ngày cuối", nên tác vụ chạy vào ngày 28–31 và một phép kiểm tra shell chỉ cho tiếp tục khi ngày mai là ngày 1.

0 0 28-31 * * Mở trong Trình phân tích biểu thức Cron

Dòng crontab dùng GNU date (date -d tomorrow); trên macOS hãy dùng date -v+1d. Quartz và Spring hỗ trợ L trực tiếp. Trên Kubernetes và GitHub Actions, thêm cùng phép kiểm tra ngày ở đầu tác vụ.

Từng trường

Trường Giá trị Khớp với
Phút 0 0
Giờ 0 0
Ngày trong tháng 28-31 28, 29, 30, 31
Tháng * Mọi giá trị
Thứ trong tuần * Mọi giá trị

Các lần chạy tiếp theo

Ví dụ: 6 lần chạy đầu tiên sau 1 tháng 1, 2026 (UTC).

  1. 00:00 Thứ 7, 31 thg 1, 2026
  2. 00:00 Thứ 7, 28 thg 2, 2026
  3. 00:00 Thứ 3, 31 thg 3, 2026
  4. 00:00 Thứ 5, 30 thg 4, 2026
  5. 00:00 CN, 31 thg 5, 2026
  6. 00:00 Thứ 3, 30 thg 6, 2026

Phiên bản dùng ngay

crontab
0 0 28-31 * * [ "$(date -d tomorrow +\%d)" = 01 ] && /path/to/command

Thêm dòng này bằng crontab -e. Lệnh chạy theo múi giờ của máy chủ, trừ khi đặt CRON_TZ hoặc TZ.

Kubernetes CronJob
apiVersion: batch/v1
kind: CronJob
metadata:
  name: last-day-of-month
spec:
  schedule: "0 0 28-31 * *"
  timeZone: "Etc/UTC"
  concurrencyPolicy: Forbid
  jobTemplate:
    spec:
      template:
        spec:
          restartPolicy: OnFailure
          containers:
            - name: job
              image: busybox:1.36
              command: ["/bin/sh", "-c", "date; echo run"]

Đặt spec.timeZone (Kubernetes 1.27+); nếu không, lịch theo múi giờ của controller manager, thường là UTC.

GitHub Actions
on:
  schedule:
    - cron: '0 0 28-31 * *'
  workflow_dispatch:

GitHub Actions luôn dùng UTC, chỉ chấp nhận khoảng cách từ 5 phút trở lên và có thể khởi chạy trễ khi tải cao.

Quartz
0 0 0 L * ?

Quartz đặt giây lên đầu và cần ? ở ngày trong tháng hoặc thứ trong tuần. Thứ được đánh số 1–7 bắt đầu từ Chủ nhật, nên dùng tên sẽ an toàn hơn.

Spring
@Scheduled(cron = "0 0 0 L * *")

Spring @Scheduled(cron = …) dùng sáu trường: giây, rồi đến năm trường quen thuộc.

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

› Vì sao % phải viết thành \% trong crontab?

Trong một dòng crontab, % nghĩa là xuống dòng (đầu vào của lệnh). Viết \% để định dạng ngày được chuyển nguyên vẹn tới shell.

› 0 0 28-31 * * chạy theo múi giờ nào?

Cron dùng múi giờ của máy hoặc dịch vụ chạy nó. Trên Linux là múi giờ hệ thống, trừ khi đặt CRON_TZ hoặc TZ; CronJob của Kubernetes hỗ trợ spec.timeZone; GitHub Actions luôn dùng UTC.

› Làm sao kiểm tra lịch này trước khi triển khai?

Mở 0 0 28-31 * * trong Trình phân tích biểu thức Cron trên trang này. Công cụ giải thích từng trường và liệt kê các lần chạy sắp tới theo giờ địa phương hoặc UTC, ngay trong trình duyệt.