Linux sunucularda zamanlanmış görev tanımlarken en sık karşılaşılan can sıkıcı hatalardan biri saat dilimi (timezone) uyuşmazlığıdır. Sabah saat 09:00'da müşterilerinize göndermek istediğiniz bir bülten e-postası sabaha karşı 06:00'da gidebilir ya da gece yarısı çalışması gereken kritik veritabanı yedeğiniz gündüz trafiğinin tam ortasında tetiklenebilir. Bunun temel sebebi, crontab içindeki zaman planının sizin yerel saatiniz ile sunucunun sistem saati arasındaki farkı kendiliğinden bilememesidir.
Klasik bir Linux cron job mekanizması, arka planda çalışan cron arka plan programının (cron daemon - crond) okuduğu sistem saati üzerinden dakikaları sayar. AWS, DigitalOcean, Hetzner veya Linode gibi bulut sağlayıcılarından açılan sanal sunucuların neredeyse tamamı varsayılan olarak UTC (Coordinated Universal Time) saat dilimiyle kurulur. Türkiye yerel saati (TSİ) ise tüm yıl boyunca UTC+3 sabit diliminde yer alır. Bu 3 saatlik fark hesaba katılmadığında UTC sunucuda 09:00 olarak tanımlanan görev Türkiye saatiyle 12:00'de, yani 3 saat geç tetiklenir.
Bu rehberde; cron daemon'un saat dilimini nasıl yorumladığını, timedatectl ile sistem saatinin doğrulanmasını, crontab dosyalarında CRON_TZ ve TZ değişkenlerinin inceliklerini, Docker konteynerlerindeki saat izolasyonunu, yaz saati (DST) risklerini ve saat karmaşasından tamamen kurtulmanın yollarını kapsamlı olarak inceliyoruz.
Cron Zaman Dilimi (Timezone) Mantığı: Sunucu Saati mi, Yerel Saat mi?
Cron arka plan servisi bağımsız bir takvim veya coğrafi konum bilgisine sahip değildir. Sistem her dakikanın 0. saniyesine ulaştığında cron servisi uyanır, geçerli sistem saatini alır ve yüklü crontab dosyalarındaki zaman kalıplarıyla eşleştirir. Eğer bir eşleşme varsa ilgili görevi alt kabukta çalıştırır.
Burada kritik ayrım şudur: Crontab dosyasına yazdığınız 0 9 * * * ifadesi mutlak bir dünya saati değildir; o ifade sadece "sistem saati 09:00 olduğunda çalıştır" anlamına gelir. Sunucunuz UTC saatiyle çalışıyorsa sistem saat 09:00 olduğunda Türkiye'de saat 12:00 olmuştur. Tersine siz Türkiye saatiyle 09:00'da çalışmasını istiyorsanız UTC çalışan bir sunucuda crontab ifadesini 0 6 * * * olarak yazmanız gerekir. İfadelerin doğru kurgulanması için crontab sözdizimi kurallarını iyi bilmek gerekir.
Bu UTC varsayımı yalnızca sunucu cron'una özgü değildir. GitHub Actions'taki schedule bloğundaki cron ifadeleri de varsayılan olarak UTC olarak yorumlanır; bu yüzden Türkiye saatiyle 09:00 hedefleyen bir workflow için UTC karşılığı olan 0 6 * * * yazılır. Tetiklemenin gecikmeye açık olması dahil davranış ayrıntıları GitHub Actions schedule rehberinde anlatılır.
Sunucu ve Donanım Saatini Denetleme (timedatectl)
Zamanlama sorunlarını çözmenin ilk adımı sunucunun o an hangi saat diliminde olduğunu ve zaman senkronizasyonunun (NTP) çalışıp çalışmadığını doğrulamaktır. Modern systemd tabanlı Linux dağıtımlarında bunun için timedatectl aracı kullanılır:
timedatectl
Komutun çıktısı aşağıdaki gibi ayrıntılı bir özet sunar:
Local time: Thu 2026-10-15 15:30:20 +03
Universal time: Thu 2026-10-15 12:30:20 UTC
RTC time: Thu 2026-10-15 12:30:20
Time zone: Europe/Istanbul (+03, +0300)
System clock synchronized: yes
NTP service: active
RTC in local TZ: no
Bu raporda dört ana satıra dikkat edilmelidir:
- Time zone: Sunucunun o an kullandığı aktif saat dilimidir. Burada
UTCgörünüyorsa sunucu evrensel saatle çalışmaktadır. - Local time: Sunucunun hesapladığı yerel saattir.
- Universal time: Standart UTC zamanıdır.
- System clock synchronized: Zaman sunucularıyla (NTP) senkronizasyonun aktif olup olmadığını gösterir. "no" ise sunucu saati zamanla kayabilir.
Adım Adım Çözüm 1: Crontab İçinde CRON_TZ ve TZ Tanımlama
Sunucunuzun genel sistem saatini UTC olarak bırakmak isteyebilirsiniz; nitekim uluslararası çalışan sunucularda ve mikroservis mimarilerinde sunucu saatini UTC tutmak en iyi güvenlik ve log tutarlılığı pratiğidir. Bu durumda tüm sunucuyu değiştirmeden Cronie gibi bu özelliği destekleyen uygulamalarda belirli bir crontab tablosuna özel saat dilimi tanımlayabilirsiniz; Debian/Ubuntu'nun klasik cron paketinde bu destek bulunmaz.
- Crontab Dosyasını Açın: Düzenlemek istediğiniz kullanıcının tablosunu açın:
crontab -e - CRON_TZ Değişkenini En Başa Ekleyin: Crontab dosyasının ilk satırına hedef saat dilimini yazın.
CRON_TZ=Europe/Istanbul # Artık aşağıdaki tüm satırlar Türkiye saatine göre çalışır 0 9 * * * /usr/bin/php /var/www/site/artisan bulten:gonder - TZ Ortam Değişkenini Tanımlayın:
CRON_TZzamanlamayı,TZise onu kullanan alt süreçlerin saat gösterimini belirler. PHP gibi uygulamaların kendi saat dilimi ayarları da olabilir. Cronie üzerinde iki değişken birlikte tanımlanabilir:CRON_TZ=Europe/Istanbul TZ=Europe/Istanbul 0 9 * * * /usr/bin/php /var/www/site/artisan bulten:gonder - Crontab Kaydını Doğrulayın: Debian/Ubuntu ve RHEL sistemlerinde kaydedilen crontab otomatik algılanır; servis yeniden yükleme komutu gerekmez. Kaydı
crontab -lile kontrol edin.
Aynı ayrım Java tarafında da geçerlidir: Spring'in @Scheduled(cron = "0 0 9 * * *") ifadesi (Spring saniye dahil 6 alan bekler) varsayılan olarak JVM'in çalıştığı saat dilimini kullanır; tetikleme saatini sunucudan bağımsız sabitlemek isterseniz zone = "Europe/Istanbul" özniteliğiyle IANA adını açıkça vermelisiniz. Bu davranışın JRE sürümlerine göre incelikleri Java Spring @Scheduled zamanlaması rehberinde örnekleriyle işlenir.
Adım Adım Çözüm 2: Sistem Saat Dilimini Kalıcı Değiştirme
Eğer sunucunuz yalnızca Türkiye lokasyonundaki kullanıcılara hizmet veriyorsa ve tüm sistem loglarının, web sunucusunun ve veritabanının yerel saatle çalışmasını istiyorsanız doğrudan sunucunun saat dilimini değiştirebilirsiniz.
Linux sistemlerde saat dilimi ayarı, /etc/localtime dosyasının /usr/share/zoneinfo/ dizinindeki ilgili bölge dosyasına sembolik bağ (symlink) yapılmasıyla belirlenir. Bu işlemi tek bir komutla güvenli şekilde gerçekleştirebilirsiniz:
sudo timedatectl set-timezone Europe/Istanbul
Bu komut arka planda şu işlemi yapar: Eski /etc/localtime dosyasını siler ve yerine /usr/share/zoneinfo/Europe/Istanbul hedefini gösteren yeni bir sembolik bağ oluşturur. Değişikliğin uygulandığını doğrulamak için:
ls -l /etc/localtime
# Çıktı: /etc/localtime -> /usr/share/zoneinfo/Europe/Istanbul
Sistem saat dilimi değiştikten sonra cron daemon'un yeni zaman dilimini hemen algılaması için servisi yeniden başlatmanız gerekir:
# Ubuntu / Debian
sudo systemctl restart cron
# RHEL / CentOS / Rocky Linux
sudo systemctl restart crond
Docker Konteynerlerinde Cron Timezone Çözümü
Mikroservis mimarilerinde veya Docker cron job yapılarında en sık düşülen tuzak, ana sunucunun saati doğru olsa bile konteynerin varsayılan UTC olarak ayağa kalkmasıdır. Docker container'ları host işletim sisteminin saat dilimini otomatik olarak devralmaz.
Dockerfile içinde Debian/Ubuntu tabanlı bir imaj hazırlarken tzdata paketini kurarak saat dilimini kalıcı hale getirebilirsiniz:
FROM debian:bullseye-slim
ENV DEBIAN_FRONTEND=noninteractive
ENV TZ=Europe/Istanbul
RUN apt-get update && apt-get install -y tzdata cron \
&& ln -snf /usr/share/zoneinfo/$TZ /etc/localtime \
&& echo $TZ > /etc/timezone \
&& dpkg-reconfigure --frontend noninteractive tzdata \
&& apt-get clean
Eğer mevcut bir imajı yeniden derlemeden docker run veya docker-compose ile çalıştırıyorsanız, host makinenin saat dilimini konteyner içine salt okunur (read-only) cilt (volume) olarak bağlayabilirsiniz:
docker run -d \
-v /etc/localtime:/etc/localtime:ro \
-v /etc/timezone:/etc/timezone:ro \
my-cron-app
Konteyner dünyasındaki bu UTC varsayılanı, bulut platformlarının zamanlayıcılarında da karşınıza çıkar: Vercel cron job tanımları da ifadeleri UTC değerlendirir; Türkiye saatiyle 09:00 hedefliyorsanız saati 3 saat geri yazmanız gerekir.
Yaz Saati (DST) Geçişlerinde Yaşanan Saat Sapmaları ve Önlemler
Türkiye 2016 yılından itibaren sabit GMT+3 (yaz saati) uygulamasına geçmiş ve kış saati uygulamasını kaldırmıştır. Ancak Avrupa Birliği, ABD ve İngiltere gibi coğrafyalarda Daylight Saving Time (DST) uygulanmaya devam etmektedir.
Eğer sunucunuz Avrupa veya Amerika saat dilimine (örneğin Europe/London veya America/New_York) ayarlıysa ilkbahar ve sonbahar aylarında iki kritik anomali yaşanır:
- İlkbahar İleri Alma (Spring Forward): Saatin ileri alındığı aralıktaki görevlerin davranışı cron uygulamasına bağlıdır. Debian cron, üç saatten küçük değişimlerde sabit saatli kaçırılmış görevleri değişimden sonra çalıştırır.
- Sonbahar Geri Alma (Fall Back): Tekrarlanan saatte mükerrer çalıştırma davranışı uygulamaya bağlıdır. Debian cron, üç saatten küçük geri almalarda sabit saatli görevin yeniden çalışmasını önler.
Bu sebeple finansal raporlama, faturalama veya veri yedekleme gibi mükerrer çalışmayı kabul etmeyen kritik görevlerde sunucunun UTC olarak yapılandırılması ve zamanlamanın UTC tabanlı yapılması hayati bir mühendislik kuralıdır.
Gerçek Kod Örnekleri
Pratikte kullanabileceğiniz doğrulanmış yapılandırma örnekleri aşağıdadır:
Örnek 1: Cronie Üzerinde CRON_TZ ile Türkiye Saatine Göre Çalışan Crontab Dosyası
# /etc/cron.d/eticaret-gorevleri
SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
CRON_TZ=Europe/Istanbul
# Log dosyası www-data tarafından yazılabilir olmalıdır
# Her iş günü Türkiye saatiyle sabah 08:30'da stok güncellemesi yap
30 8 * * 1-5 www-data /usr/bin/php /var/www/site/cron/stok.php >> /var/www/site/stok.log 2>&1
# Her pazar gecesi 23:45'te haftalık rapor oluştur
45 23 * * 0 www-data /usr/bin/python3 /var/www/site/scripts/rapor.py
Örnek 2: Betik İçin Saat Dilimi Tanımlama (Inline TZ)
Eğer kullandığınız cron daemon CRON_TZ değişkenini satır başında desteklemiyorsa, komut önündeki TZ=... yalnızca betiğin saat gösterimini etkiler, tetikleme saatini değiştirmez. Aşağıdaki 06:00 kaydı UTC sunucuda Türkiye saatiyle 09:00'a karşılık gelir:
0 6 * * * TZ=Europe/Istanbul /usr/bin/php /var/www/site/gorev.php
Sık Karşılaşılan Hatalar ve Çözümleri
Saat dilimi uyumsuzluğundan kaynaklanan en popüler problemler ve çözüm yöntemleri:
Nedeni: Sunucu BIOS/OS saati UTC zaman diliminde kalmıştır ve crontab kullanıcısı yerel saat dilimini belirtmeden görevi planlamıştır.
Çözümü: Sunucu genelinde kalıcı düzeltme için
sudo timedatectl set-timezone Europe/Istanbul çalıştırın ya da Cronie gibi destekleyen bir uygulamada crontab başına CRON_TZ=Europe/Istanbul ekleyin.
Nedeni: Kullanılan cron uygulaması
CRON_TZ ile ayrı zamanlamayı desteklemiyor olabilir; Debian/Ubuntu klasik cron paketi bu değişkeni zamanlama için kullanmaz.Çözümü: Sistem saat dilimini değiştirin veya saat alanını sunucunun saat dilimine göre dönüştürün. Komut önüne
TZ=Europe/Istanbul eklemek tetikleme zamanını değiştirmez.
Nedeni: DST kullanan ülkelerde saatlerin 02:00'den 03:00'e alınması sırasında aradaki 60 dakikalık zaman dilimi sistem saatinde hiç yaşanmamıştır.
Çözümü: Kritik görevlerinizi 02:00-03:00 aralığı yerine saat 01:30 veya 03:30'a planlayın ya da zamanlamayı UTC'ye taşıyın;
CRON_TZ=UTC yalnızca destekleyen cron uygulamalarında geçerlidir. Görevleriniz hiç tetiklenmiyorsa cron job çalışmıyor rehberimizdeki temel adımları izleyin.
Nedeni: Host makinenin saati yerel olarak ayarlanmışken Docker container'ı izole edilmiş UTC saat diliminde çalışmaktadır.
Çözümü: Konteyneri başlatırken
-v /etc/localtime:/etc/localtime:ro parametresini ekleyin veya container ortamına -e TZ=Europe/Istanbul çevre değişkenini tanımlayın.
cronjob.com.tr ile HTTP Tabanlı Alternatif Kurulum (İş Bazında Saat Dilimi)
Farklı sunucularda saat dilimlerini yönetmek, NTP sapmalarını takip etmek ve Docker konteynerlerinde tzdata paketleriyle uğraşmak hem zaman alıcıdır hem de operasyonel hata riskini artırır. Özellikle dağıtık sunucu ortamlarında her makinenin saati birkaç saniye kayabilir veya farklı yapılandırılmış olabilir.
cronjob.com.tr bulut tabanlı zamanlama servisi, tüm saat dilimi karmaşasını ortadan kaldıran modern bir HTTP tetikleme alternatifidir. Platformumuz üzerinde oluşturduğunuz her zamanlanmış görev için doğrudan panelden istediğiniz saat dilimini (varsayılan olarak Europe/Istanbul) seçebilirsiniz. Sunucunuz ister Frankfurt'ta UTC olarak çalışsın, ister Amerika'da EST diliminde olsun; cronjob.com.tr görevinizin zamanlamasını seçtiğiniz saat dilimine göre değerlendirir.
Kayıt olmak tamamen ücretsizdir ve kredi kartı bilgisi talep edilmez. Bir web servisini zamanlamak için şu adımları uygulayabilirsiniz:
- Uç Nokta Belirleme: Sunucunuzda tetiklenecek işlemi güvenli bir HTTP uç noktası olarak tanımlayın (örneğin
https://api.siteniz.com/cron/fatura-olustur). İsteğin güvenliği için özel bir gizli token başlığı (örneğinX-Cron-Token: GizliAnahtar123) belirleyebilirsiniz. - Zamanlama Ayarı: 60 saniyeden (1 dakika) başlayan hazır aralıkları veya standart 5 alanlı cron ifadesini (örneğin
30 9 * * 1-5) kullanabilirsiniz. Saat dilimi açılır menüsünden "Europe/Istanbul" seçildiğinde DST geçişlerinden etkilenmeyen kararlı bir zamanlama elde edilir. - Gelişmiş HTTP Desteği: GET, POST, PUT, PATCH, DELETE, HEAD ve OPTIONS metotları arasından dilediğinizi seçebilir, istek gövdesi (payload) veya HTTP Basic Auth ekleyebilirsiniz. İstek zaman aşımı aralığa göre otomatik ayarlanır (5 dakikalık veya cron ifadeli işlerde 290 saniyeye kadar bekleme imkanı sunulur).
- İzleme ve Bildirim: Ardışık hata sayısı eşiği (varsayılan 3, 1–20 arası ayarlanabilir) aşıldığında sistem yöneticisine "erişim sorunu" e-postası gönderilir; sunucunuz düzeldiğinde kesinti süresiyle birlikte "düzeldi" bildirimi iletilir. Aynı iş için bildirimler arasında en az 60 dakika bulunur. Tüm çalıştırma kayıtları, durum kodları ve ilk ~64 KB'lık yanıt gövdesi 7 gün boyunca log konsolunda saklanır.
Sıkça Sorulan Sorular (SSS)
Crontab varsayılan olarak hangi saat dilimini kullanır?
Cron daemon (crond), crontab dosyası içinde özel bir zaman dilimi belirtilmediği sürece doğrudan sunucu işletim sisteminin geçerli sistem saat dilimini (system timezone) baz alır.
CRON_TZ tüm Linux dağıtımlarında geçerli midir?
Hayır. CRON_TZ, Red Hat, CentOS ve Rocky Linux sistemlerindeki Cronie tarafından desteklenir; Debian/Ubuntu klasik cron paketinde desteklenmez. TZ değişkeni alt sürecin saat gösterimini etkiler, tetikleme saatini değiştirmez.
Sunucu saatini UTC tutmak neden önerilir?
Sunucu saatini UTC olarak yapılandırmak, yaz ve kış saati (DST) geçişlerinde görevlerin mükerrer çalışmasını veya atlanmasını engeller ve dağıtık sunucu mimarilerinde log tutarlılığı sağlar.
Türkiye'de sabit GMT+3 nasıl ayarlanır?
Linux terminalinde sudo timedatectl set-timezone Europe/Istanbul komutunu çalıştırarak sistem saatinizi Türkiye'nin sabit UTC+3 saat dilimine kalıcı olarak ayarlayabilirsiniz.
Hemen Ücretsiz Cron Job Oluşturun
Frankfurt'taki UTC sunucunuzda çalışan bir uç noktayı, cronjob.com.tr panelinde işin saat dilimini Europe/Istanbul seçerek Türkiye saatiyle tetikleyebilirsiniz; her iş için saat dilimi ayrıca belirlenir.
Ücretsiz Başla →