When cronjobs consistently run at unexpected hours (particularly showing an 8-hour discrepancy in your case), we're typically dealing with one of these fundamental timing layers:
# Current time verification commands
date # System clock
timedatectl # Systemd time management
ls -l /etc/localtime # Timezone symlink verification
The Linux time system operates through several layers:
- Hardware Clock (RTC)
- System Clock (kernel time)
- Timezone Configuration
- Cron Daemon's Environment
Your specific issue suggests either:
- Undetected timezone misconfiguration
- Cron running with a different environment than shell
- Improper service restart after tzdata changes
1. Verify actual cron environment:
# Create a test cron job that outputs environment
* * * * * /usr/bin/env > /tmp/cronenv.log
2. Check systemd services (modern Ubuntu):
systemctl status cron
journalctl -u cron -b --no-pager | grep -i timezone
3. Compare shell vs cron environments:
# In shell
echo $TZ
cat /etc/timezone
# In cron test job
* * * * * echo $TZ >> /tmp/crontz.log
Option A: Force system-wide timezone
sudo unlink /etc/localtime
sudo ln -s /usr/share/zoneinfo/America/Chicago /etc/localtime
sudo dpkg-reconfigure -f noninteractive tzdata
sudo systemctl restart cron
Option B: Explicitly set TZ in crontab
TZ=America/Chicago
0 4 * * * /path/to/command
Cron often runs with a minimal environment. To debug:
# Enhanced test job
* * * * * printenv > /tmp/fullcronenv.log 2>&1
* * * * * ls -l /etc/localtime >> /tmp/cronsymlink.log 2>&1
If you need to ensure proper environment inheritance:
# At crontab top
SHELL=/bin/bash
BASH_ENV=/etc/profile
After making changes:
# Check active timezone
date
timedatectl
# Verify cron sees correct time
* * * * * date >> /tmp/crondate.log
Remember that some cron implementations (like Vixie cron) may cache timezone data. A full service restart is often needed:
sudo service cron restart
When cron jobs execute earlier or later than expected, it's often related to timezone settings. In your case, cron jobs set to run at 4 AM (UTC) are triggering 8 hours early, suggesting a timezone mismatch between the system and cron's configuration.
First, verify your system's current time settings:
date
timedatectl status
This should show your configured timezone (CST in your case) and current system time.
Cron typically uses the system timezone, but there are exceptions:
- Some cron implementations (like Vixie cron) use the system timezone
- Others may use UTC by default
- Environment variables can override this behavior
Check if cron is using a different timezone than your system:
sudo grep -i 'TZ' /etc/crontab /etc/cron.*/*
grep -i 'TZ' /etc/environment
Option 1: Explicitly set timezone in crontab
TZ=America/Chicago
0 4 * * * command
Option 2: Modify system-wide cron configuration
sudo nano /etc/default/cron
# Add or modify:
CRON_TZ=America/Chicago
Option 3: Adjust your cron schedule
# If cron is using UTC and you want 4 AM CST (which is 10 AM UTC)
0 10 * * * command
After making changes, monitor the next execution:
sudo tail -f /var/log/syslog | grep CRON
- Check for user-specific crontabs that might have different timezone settings
- Verify daylight saving time handling if applicable
- Consider using systemd timers for more precise time control
Create a timer unit file:
[Unit]
Description=Run daily job at 4 AM CST
[Timer]
OnCalendar=*-*-* 04:00:00
TimeZone=America/Chicago
Persistent=true
[Install]
WantedBy=timers.target