Migrating production infrastructure? Get up to ₹10,000 in migration credits. Apply now
voroaBlog
Background Workers

Cron Timezone: Running Cron Jobs in IST on a UTC Server

· · 6 min read

Cron timezone for India, converting IST to UTC and the day-shift and month-start traps

Cron timezone problems look like random failures: a report arrives at 2:30 pm instead of 9 am, or a Monday job fires on Sunday night. The cause is almost always the same. Your schedule is read in UTC, and you wrote it in Indian time.

This guide shows how to convert correctly, the two traps that a simple “subtract 5:30” misses, and how each platform and library lets you set the zone. The conversions below were generated with Python’s zoneinfo, not worked out by hand.

On this page

Advertisement

Which timezone does cron use?

Classic Linux cron uses the server’s system timezone. Check it with:

bash
timedatectl          # or: date

Most cloud servers and containers are set to UTC. Most hosted schedulers also use UTC by default. India Standard Time is UTC plus 5 hours 30 minutes, all year: India has no daylight saving, so the offset never changes.

IST to UTC conversion table

For a job you want on Monday in India:

You want (IST, Monday) UTC time Cron line on a UTC server
Midnight Sunday 18:30 30 18 * * 0
2:00 am Sunday 20:30 30 20 * * 0
5:29 am Sunday 23:59 59 23 * * 0
5:30 am Monday 00:00 0 0 * * 1
9:00 am Monday 03:30 30 3 * * 1
9:30 am Monday 04:00 0 4 * * 1
Noon Monday 06:30 30 6 * * 1
6:00 pm Monday 12:30 30 12 * * 1
11:30 pm Monday 18:00 0 18 * * 1

For daily jobs drop the last field: 9 am IST every day is 30 3 * * *.

Ranges convert the same way. “Every hour from 9 am to 6 pm IST” is 30 3-12 * * *. Because of the half hour, it fires at 30 minutes past each UTC hour, which is on the hour in India.

Trap 1: before 5:30 am IST, the day changes

Look at the top of the table. Anything earlier than 5:30 am in India happens on the previous day in UTC.

Diagram: a 24-hour IST day lined up against UTC; IST midnight to 5:29 am falls on the previous UTC day, so a Monday 2 am IST job must be written for Sunday in UTC

So a “Monday 2 am” backup written as 30 20 * * 1 runs on Tuesday 2 am in India. The correct line is 30 20 * * 0, with Sunday as the day. Weekday ranges shift too: “2 am IST, Monday to Friday” becomes 30 20 * * 0-4.

This is the most common reason a weekly job seems to run on the wrong day.

Trap 2: the first of the month

The same shift hits dates. “2 am IST on the 1st of every month” is 20:30 UTC on the last day of the previous month.

Standard cron cannot say “last day of the month”, because months have 28 to 31 days. You have two options: run the job at 5:30 am IST or later, so the date stays the same in UTC, or use a scheduler that lets you set the timezone to Asia/Kolkata.

Setting the timezone, platform by platform

Where it runs Default zone Can you change it?
Your own Linux server The system timezone Change the system zone, or use CRON_TZ where your cron supports it (cronie does; Ubuntu’s default cron does not)
GitHub Actions schedule UTC Its docs now describe setting an IANA timezone
Vercel Cron Jobs UTC only The newer Schedules feature adds timezones
Heroku Scheduler UTC No; adjust the time yourself
Render, Railway cron UTC Not documented as configurable
Voroa Cron Job or Scheduled Task IST It is IST already

Sources: each platform’s documentation, checked on 7 November 2026, including the GitHub Actions events page. Platform details are in our posts on Vercel cron jobs and Heroku Scheduler.

Setting it in code

In-app schedulers take a timezone option. Use the IANA name Asia/Kolkata; avoid fixed offsets such as +05:30 where a name is accepted.

js
// node-cron
cron.schedule('0 9 * * *', job, { timezone: 'Asia/Kolkata' });
python
# APScheduler
BlockingScheduler(timezone="Asia/Kolkata")

# Celery beat
app.conf.timezone = "Asia/Kolkata"

Without the option, node-cron and APScheduler fall back to the server’s zone, usually UTC. Celery falls back to UTC whatever the server’s zone is. Our tests of node-cron, APScheduler and Celery beat cover the other things these schedulers get wrong.

The schedule and the clock are not the same

Setting the schedule’s timezone decides when the job starts. It does not change the clock your code reads inside the job.

A job scheduled for 9 am IST can still see a UTC time from new Date().getHours() or a naive datetime.now() if the container runs on UTC. If your job names a file by date or picks “yesterday’s” records, set the zone in the code too, or use timezone-aware functions with Asia/Kolkata.

Cron jobs in IST on Voroa

Voroa’s Cron Jobs and Scheduled Tasks read schedules in India Standard Time, so 0 9 * * * means 9:00 am IST and 0 2 * * 1 means Monday 2 am IST, with no conversion.

The container’s own clock may still be UTC, as above, so read the date carefully inside the job. Runs are skipped while the service is stopped, and a slow run can overlap the next, so keep jobs safe to run twice. See scheduling a task on Voroa, and the background workers page for long-running processes.

FAQ

What timezone does cron use? The server’s system timezone. On most cloud servers and hosted schedulers that is UTC.

How do I convert IST to UTC for cron? Subtract 5 hours 30 minutes. 9 am IST is 30 3 * * *. For times before 5:30 am IST, also move the day back by one.

Why does my Monday cron job run on Tuesday? It is set for early morning IST but written with Monday in UTC. Early IST hours are the previous UTC day, so write Sunday.

Can I set a timezone in a crontab? With cronie, yes, using CRON_TZ=Asia/Kolkata. Ubuntu’s default cron ignores it, so change the system timezone instead.

Does India have daylight saving time? No. IST is UTC plus 5:30 all year, so a converted schedule never needs adjusting.

Which timezone name should I use for India? Asia/Kolkata. It is the IANA name that libraries and platforms accept.

Conversions generated with Python zoneinfo on 7 November 2026. Found something out of date? Write to [email protected].

Advertisement