ShareYourGroupShareYourGroupCron Helper

Cron expression for the 1st and 15th of every month

At 09:00, on days 1 and 15 of the month.

Five fields for Linux, GitHub Actions and Kubernetes (minute hour day month weekday). Six or seven for Quartz. Nothing you type leaves your device.

What it means and when to use it

A comma-separated list in the day-of-month field gives a semi-monthly schedule: payslips on the 1st and 15th, a mid-month reminder, or a report for each half of the month. Because days 1 and 15 exist in every month, the job runs 24 times a year.

Watch out for this

Here is where the day-of-week field must stay a star. The cron manual gives the example 30 4 1,15 * 5, which runs at 4:30 on the 1st and 15th and also on every Friday, since both day fields are set. The tool above shows both parts. If you only want the two dates, keep the last field as *. If payday moves to the previous working day when the 15th is a Sunday, put that logic in the script.

What each field says

FieldWrittenMeans
Minute00
Hour99
Day of month1,151, 15
Month*every month
Day of week*every day of the week

An example of the next runs

If it were Friday 13 November 2026 at 10:20 UTC, the next six runs would be these. Times are shown in UTC and in India time (UTC+5:30).

UTCIndia time
Sun 15 Nov, 09:00Sun 15 Nov, 14:30
Tue 1 Dec, 09:00Tue 1 Dec, 14:30
Tue 15 Dec, 09:00Tue 15 Dec, 14:30
Fri 1 Jan, 09:00Fri 1 Jan, 14:30
Fri 15 Jan, 09:00Fri 15 Jan, 14:30
Mon 1 Feb, 09:00Mon 1 Feb, 14:30

The same schedule in other places

Quartz

Quartz has a seconds field in front, uses ? in one day field, and counts Sunday as 1:

0 0 9 1,15 * ?

GitHub Actions

Scheduled workflows run in UTC unless you add a time zone. In the workflow file:

on:
  schedule:
    - cron: '0 9 1,15 * *'

Kubernetes CronJob

In a CronJob manifest the schedule goes in spec.schedule. Without spec.timeZone, it is read in the time zone of the cluster's controller:

spec:
  schedule: "0 9 1,15 * *"
  timeZone: "Etc/UTC"

A crontab line to copy

The command is made up. Replace it with your own and use full paths:

0 9 1,15 * * /home/me/bin/payroll-reminder.sh >> /home/me/payroll.log 2>&1

Questions

Why did my 1st and 15th job also run on Fridays?

You set a value in the day-of-week field too. Cron treats the two day fields as "either one", so every Friday matched. Set the day-of-week field back to a star.

This is an independent guide and tool. It is not connected with crontab.guru, Quartz, GitHub, Kubernetes, Spring or the Linux projects named here. Product names belong to their owners.