Cron Expressions and Timezones: UTC vs Local Time Explained
Table of Contents
Timezones are one of the most common sources of cron job bugs. A backup job that runs at 2 AM local time suddenly runs at 3 AM after daylight saving. A report that should go out Monday morning fires Sunday evening because the server is in UTC.
This guide explains how cron handles time, how to configure timezone-aware schedules, and how to convert between local time and UTC. Build your schedule in our free cron expression generator and verify the next run times before deploying.
Which Timezone Does Cron Use?
Standard cron runs in the system timezone of the machine — whatever timezone the OS is configured with. So if your Linux server is set to UTC, all cron jobs run in UTC. If it's set to America/New_York, they run in Eastern time.
To check your system timezone:
timedatectl # Linux (systemd) date # Shows current time with timezone offset cat /etc/timezone # Often shows the timezone name directly
Cloud servers (AWS EC2, GCP, DigitalOcean) default to UTC. Most cloud-based cron services (GitHub Actions, AWS EventBridge) also run in UTC. This is actually a best practice — UTC never changes, so your 2 AM backup runs at 2 AM UTC year-round, regardless of daylight saving in any timezone.
Converting Local Time to UTC for Cron Jobs
If your server runs UTC and you want a job at 9 AM Eastern, you need to know the UTC offset for Eastern time. Eastern time has two offsets: UTC-5 in winter (EST) and UTC-4 in summer (EDT).
| Desired Local Time | Timezone | UTC (Winter / EST) | UTC (Summer / EDT) |
|---|---|---|---|
| 9:00 AM | Eastern | 14:00 | 13:00 |
| 9:00 AM | Central | 15:00 | 14:00 |
| 9:00 AM | Mountain | 16:00 | 15:00 |
| 9:00 AM | Pacific | 17:00 | 16:00 |
| 9:00 AM | London (GMT) | 9:00 | 8:00 (BST) |
| 9:00 AM | Berlin (CET) | 8:00 | 7:00 (CEST) |
This is the core daylight saving problem: if you want a job to run at 9 AM Eastern year-round, you need to update the cron expression twice a year (or use timezone-aware scheduling).
Sell Custom Apparel — We Handle Printing & Free ShippingPlatform-Specific Timezone Configuration
Linux crontab (per-user timezone): Add CRON_TZ at the top of your crontab:
CRON_TZ=America/New_York 0 9 * * 1-5 /path/to/script.sh
Spring Boot @Scheduled: Use the zone attribute:
@Scheduled(cron = "0 0 9 * * MON-FRI", zone = "America/New_York")
Kubernetes CronJob (1.25+): Use the timeZone field:
spec: schedule: "0 9 * * 1-5" timeZone: "America/New_York"
GitHub Actions: No timezone support — always UTC. Hardcode the UTC equivalent or accept the DST offset.
Daylight Saving Gotchas in Cron Jobs
DST is the most common cause of cron job timing surprises. When clocks spring forward, the "lost" hour at 2 AM means any cron job scheduled at 2:xx AM may be skipped entirely. When clocks fall back, the repeated hour means a job might run twice.
How different platforms handle this:
- Linux crontab — behavior during DST transitions is implementation-specific. Most modern crond implementations skip the lost hour and run the repeated hour twice (the safe behavior).
- Spring Boot with zone= attribute — Java handles DST correctly. A job at 9 AM Eastern will always run at 9 AM Eastern, regardless of whether it's EST or EDT.
- Kubernetes with timeZone field — Uses system timezone data and handles DST correctly.
- UTC-only systems — UTC never changes, so there are no DST transitions. This is the simplest approach for jobs where the exact local time doesn't matter.
Best practice: run your servers in UTC and only convert to local time at the application level. Store all timestamps in UTC. Schedule cron jobs in UTC unless the local time precision genuinely matters (like "send this email at 9 AM recipient's time").
Verifying Your Timezone-Aware Cron Schedule
Before deploying any timezone-sensitive cron job, verify it runs at the exact times you expect. Our crontab visualizer shows next run times in your local browser timezone — useful for sanity-checking that a UTC expression maps to the local times you intend.
For cross-timezone verification: build the expression, visualize it, then check the timestamps against the Unix timestamp converter to confirm the UTC-to-local conversion is correct.
When in doubt, document the timezone alongside any cron expression in your code comments or YAML files. Future you (and your team) will thank you.
Try It Free — No Signup Required
Runs 100% in your browser. No account, no install, no limits.
Open Free Cron GeneratorFrequently Asked Questions
Does cron run in UTC or local time?
By default, cron uses the system timezone of the machine it runs on. Cloud servers typically default to UTC. To check your system timezone on Linux, run "timedatectl" or "cat /etc/timezone". You can override the timezone per crontab with the CRON_TZ variable.
How do I make a cron job ignore daylight saving time changes?
The simplest approach is to schedule in UTC, which never changes for DST. If your platform supports named timezones (Spring Boot's zone= attribute, Kubernetes timeZone field, or CRON_TZ in Linux crontab), use a full timezone identifier like "America/New_York" rather than a fixed UTC offset, and the system will handle DST transitions automatically.
My cron job ran at the wrong time after daylight saving. How do I fix it?
If you're using a fixed UTC offset (like UTC-5 for EST), update the cron expression when DST changes. Better long-term: switch to a platform that supports named timezone configuration, so the timezone software automatically accounts for DST. Alternatively, run in UTC and convert at the application level.

