TimezonesReference7 min read

Cron Jobs and Timezones: The Complete Guide

Timezone issues are one of the most common sources of cron bugs. Jobs fire at the wrong time, or drift by an hour when DST changes. This guide covers the root causes and exactly how to fix them on every major platform.

Why Cron Defaults to UTC (or System Time)

Standard Linux cron runs jobs according to the system clock timezone. On a server configured to UTC (common for cloud VMs), all jobs run in UTC regardless of where you are.

Cloud-native schedulers like GitHub Actions and older Kubernetes versions go further — they always use UTC with no option to change it. This is intentional: UTC is unambiguous and never changes for DST.

The problem arises when developers write cron schedules in their local time, forgetting the server is UTC. A job written as 0 9 * * * expecting 9 AM New York time fires at 9 AM UTC (which is 4 or 5 AM in New York).

Daylight Saving Time (DST) Warning

If your server is set to a DST-observing timezone (e.g., America/New_York), your cron jobs will shift by one hour twice a year when clocks change. During the spring-forward transition, one occurrence is also skipped entirely. The safest practice for servers is to keep them in UTC and convert schedules manually or use a platform with native timezone support.

Platform-by-Platform Timezone Support

Linux crontab (Vixie cron)System timezone

Set `TZ=` at the top of the crontab to apply to all jobs below it. You can also set it per-job inline on some systems.

TZ=America/New_York
0 9 * * * /path/script.sh
GitHub ActionsAlways UTC

GitHub Actions cron always runs in UTC. There is no way to set a timezone. You must convert your target time to UTC manually.

on:
  schedule:
    - cron: '0 14 * * *'  # 14:00 UTC = 9:00 AM EST
Kubernetes CronJobController timezone (usually UTC)

Kubernetes 1.27+ added the `timeZone` field to CronJob spec. For older clusters, the schedule runs in the controller-manager's local time (usually UTC).

spec:
  schedule: "0 9 * * *"
  timeZone: "America/New_York"
AWS EventBridge SchedulerUTC (default), configurable

EventBridge Scheduler natively supports timezones. Select your timezone when creating the schedule in the console or via API. Note: EventBridge cron uses 6 fields (adds year).

cron(0 9 * * ? *)
Timezone: America/New_York
GCP Cloud SchedulerUTC (default), configurable

GCP Cloud Scheduler supports any IANA timezone. Set it in the UI or via `--time-zone` flag. Standard 5-field cron syntax.

schedule: "0 9 * * *"
timeZone: "America/New_York"
Azure Functions (timer trigger)UTC (default), configurable

Azure uses Windows timezone names (e.g., 'Eastern Standard Time'). Set `WEBSITE_TIME_ZONE` or `TZ` app setting. Note: Azure timer trigger uses 6-field NCRONTAB (seconds first).

// function.json
"schedule": "0 0 9 * * *"

// App Setting:
WEBSITE_TIME_ZONE = Eastern Standard Time

Common Local Time → UTC Conversions

For platforms that require UTC (GitHub Actions), use this table to convert your intended schedule. Remember that DST offsets change seasonally.

Local TimeUTCCron Expression
9:00 AM ET (EST, UTC-5)14:00 UTC0 14 * * *
9:00 AM ET (EDT, UTC-4)13:00 UTC0 13 * * *
9:00 AM PT (PST, UTC-8)17:00 UTC0 17 * * *
9:00 AM PT (PDT, UTC-7)16:00 UTC0 16 * * *
9:00 AM CET (UTC+1)8:00 UTC0 8 * * *
9:00 AM IST (UTC+5:30)3:30 UTC30 3 * * *
9:00 AM JST (UTC+9)0:00 UTC0 0 * * *
Midnight ET (EST, UTC-5)5:00 UTC0 5 * * *

Best Practices

Use UTC for server cron

Keep servers in UTC and convert schedule times manually. Avoids DST surprises.

Use IANA timezone names

Prefer `America/New_York` over `EST` — named zones handle DST automatically.

Document the timezone in comments

Add a comment like `# 9:00 AM ET (UTC-5)` next to each cron entry.

Test around DST transitions

If timing precision matters, verify behavior around the spring-forward and fall-back dates.

Don't set servers to DST-observing zones

Production servers in `America/New_York` will shift all cron schedules twice per year.

Don't assume cloud = UTC

GCP and AWS support non-UTC timezones. Always check your scheduler's timezone setting.

Preview next run times with timezone support

Our Cron Debugger shows the next 10 run times in your chosen timezone — helpful for validating UTC conversions.