The five cron fields
A crontab line schedules a job with five space-separated fields, in this order: minute (0-59), hour (0-23, 24-hour clock), day of month (1-31), month (1-12 or JAN-DEC) and day of week (0-7 or SUN-SAT, where both 0 and 7 mean Sunday). Some schedulers - Quartz, Spring, and many container platforms - accept a sixth field at the front for seconds. This parser accepts either form and tells you which one it saw.
Every field supports four operators. An asterisk * means every value. A comma lists values: 1,15. A hyphen gives a range: 9-17. A slash gives a step: */15 in the minute field means 0, 15, 30 and 45, and 0-30/10 means 0, 10, 20 and 30. Ranges and steps combine, so 2-10/3 is 2, 5, 8. Cron does not sleep between runs; it wakes every minute and fires any job whose fields all match the current time.
The day-of-month and weekday trap
The one rule that surprises almost everyone is how the two day fields interact. If both day of month and day of week are restricted, cron runs the job when either matches, not both. So 0 0 1 * 1 fires on the first of every month and on every Monday, which is usually not what the author meant. If exactly one of the two is *, only the other one applies, which is the normal case. To get "the first Monday of the month" you need a day-of-month range plus a weekday, like 0 0 1-7 * 1, which this parser handles correctly.
Worth knowing too: 0 9 * * 1-5 reads as 9:00 AM Monday through Friday, and that is the most common business schedule in crontabs. */15 * * * * fires at :00, :15, :30 and :45 of every hour, 96 times a day. A step never wraps past the end of a range, so */40 in the minute field fires at :00 and :40 only, skipping the 20-minute remainder at the top of the next hour.
Time zones, environment and testing
The preview above uses your computer's local time zone. Real cron uses the daemon's time zone, which on most Linux servers and in most Docker images is UTC. If your job must run at 9:00 AM Eastern, either set CRON_TZ=America/New_York at the top of the crontab (supported by Vixie cron and cronie) or convert the hour yourself and remember that daylight saving time shifts it twice a year. Jobs scheduled inside the hour that a spring-forward skips may not run at all; jobs inside a fall-back hour may run twice.
Two more practical notes. Cron runs with a minimal environment - typically only HOME, PATH=/usr/bin:/bin, SHELL and LOGNAME - so always use absolute paths to binaries and source any profile your script needs. And a percent sign in a crontab command is special: it becomes a newline unless you escape it as \%, which bites people writing date +%Y-%m-%d in a cron line. Test with crontab -l, and check /var/log/syslog or journalctl -u cron to confirm the job actually fired.