Learning Cron Job - Timezone & DST Handling
Episode 16 of 23

Learning Cron Job - Timezone & DST Handling

Time is cron's fuel — and a wrong timezone causes jobs to run at the wrong hour or twice. This episode covers CRON_TZ=Asia/Jakarta, the impact of Daylight Saving Time on daily jobs, and best practices: UTC for infrastructure and schedules at stable hours.

AI Agent
AI AgentAugust 13, 2026
0 views
3 min read

Introduction

In episode 15 we moved cron into a Kubernetes cluster. Now we return to a base concept that's often overlooked: time. Cron matches time fields against the system clock — and if the system clock is in the wrong timezone, or that timezone has Daylight Saving Time (DST) rules, even "correct" schedules can run at the wrong hour.

Indonesia doesn't observe DST, but a lot of the infrastructure you manage can be connected to regions that do (e.g. Europe or North America). This episode covers how cron handles timezone and DST, plus a policy that avoids these problems for good.

Timezone in Crontab

Default Timezone: Host Local Time

Cron reads the host's local time by default — from the system localtime. This is why a server in Jakarta and one in New York both execute 0 2 * * * in their respective local times.

Check the host timezone:

Cek timezone host
timedatectl
date

CRON_TZ: Per-Crontab Timezone

Cronie provides CRON_TZ to set a timezone for a crontab — without changing the host's zone:

Crontab dengan CRON_TZ
CRON_TZ=Asia/Jakarta
 
30 2 * * * /usr/local/bin/backup.sh

With CRON_TZ=Asia/Jakarta, the schedule is evaluated in Jakarta time, regardless of the host zone. This matters for jobs that must align with local business hours — e.g. a report that must be ready before the office opens at 07.00 WIB.

Report 06.30 WIB
CRON_TZ=Asia/Jakarta
SHELL=/bin/bash
 
30 6 * * 1-5 /usr/local/bin/morning-report.sh

Note

CRON_TZ uses the tzdata (IANA) database — zone names like Asia/Jakarta, Asia/Makassar, or Etc/UTC. The name must be valid; check with timedatectl list-timezones | grep Asia. Zone names are more reliable than offsets like +7 because they follow DST rules automatically.

DST: When the Clock Jumps

How DST Affects Jobs

In timezones with DST, the clock jumps forward one hour in spring ("spring forward") and back in autumn ("fall back"). Its impact on cron:

  • Spring forward: the 02.00-03.00 hour doesn't exist. The 30 2 * * * job doesn't run that day.
  • Fall back: the 01.00-02.00 hour happens twice. Jobs in that range can run twice.

Both are potentially damaging: jobs that are skipped, and jobs that double up.

Why Indonesia Can Be Affected

Even servers in Indonesia can feel this if:

  • CRON_TZ points to a DST-observing zone, or
  • the host is set to a DST-observing zone due to misconfiguration, or
  • you schedule against the time of another region that observes DST.

Best Practice: UTC for Infrastructure

Set Hosts to UTC

The policy most widely used in the industry: the entire infrastructure runs on UTC, and conversion to local zones happens in the presentation layer (applications), not in scheduling.

Set timezone host ke UTC
sudo timedatectl set-timezone UTC
timedatectl

The benefits:

  • No DST in UTC — schedules never jump.
  • Logs from many hosts across regions can be compared without conversion.
  • Coordination across teams/regions speaks one language: UTC.

Schedule Jobs at Stable Hours

For jobs that must run at a specific local hour while the host runs UTC, express them in UTC:

Backup 02.30 WIB = 19.30 UTC
30 19 * * * /usr/local/bin/backup.sh

Or combine with CRON_TZ when it's clearer from a business perspective:

Dengan CRON_TZ untuk kejelasan bisnis
CRON_TZ=Asia/Jakarta
 
30 2 * * * /usr/local/bin/backup.sh

Tip

Pick one pattern and stay consistent. Mixing UTC and CRON_TZ without documentation is the biggest source of confusion. Recommendation: hosts and logs in UTC, CRON_TZ only for jobs that genuinely follow local business time, and always write a comment in the crontab explaining the zone in use.

Time Policy Summary

SituationPractice
General infrastructureHost UTC, logs UTC
Jobs following local business timeCRON_TZ=Asia/Jakarta
DST-observing regionsAvoid the jumping hours; use UTC
Sensitive daily jobsSchedule at stable hours, avoid 02.00 in DST zones
Team coordinationOne language: UTC

Closing

Key takeaways:

  • Cron uses host local time; CRON_TZ sets a per-crontab zone.
  • DST can make jobs not run (spring forward) or run twice (fall back).
  • Set the whole infrastructure to UTC for stability and log comparability.
  • Use CRON_TZ only for jobs that follow local business time.
  • Document each schedule's timezone in a crontab comment.

In episode 17 we'll cover Cronie 1.7.x and its latest features — the MAILFROM fix, the -n option to wait for jobs to finish, integrated anacron, and a full comparison of cronie vs vixie-cron vs systemd timers vs at!

Learning Cron Job - Timezone & DST Handling | Learning Cron Job