Bilgisayar saati 1970'ten beri saniye sayıyor: 2038 sorunu ve artık saniyenin sonu
· Bilim, Teknoloji
Terminale date +%s yazınca ekrana tek bir sayı geliyor. Ben bu yazıyı hazırlarken 1.792.761.102 çıktı. Bu, 1 Ocak 1970 gecesinden o ana kadar geçen saniye sayısı. Dosya tarihlerinden çerez sürelerine, günlük kayıtlarından sertifikalara kadar pek çok yerde zaman böyle tek bir tam sayı olarak tutuluyor. Bu sayının hikâyesinde şu sıralar iki tarih öne çıkıyor: 19 Ocak 2038'de 32 bitlik sayaçlar doluyor, 20 Mayıs 2027'den itibaren de dünya saati artık saniye eklemeyi bırakıyor. İkisi sık sık birbirine karıştırılıyor, oysa aynı sorun değiller.
- Unix zamanı, 1 Ocak 1970 00:00:00 UTC'den beri geçen saniye sayısıdır.
- İşaretli 32 bitlik sayaç 19 Ocak 2038'de 03:14:07 UTC'de dolar. 64 bitlik sayaç bu sorunu pratikte ortadan kaldırır.
- Unix zamanı artık saniyeleri saymaz. Ekim 2026'daki kararla UTC, 20 Mayıs 2027'den itibaren artık saniye almayacak.
- Biri sayının kaç bit olduğuyla, öteki saatin nasıl tanımlandığıyla ilgili. Birbirini çözmüyorlar.
Bir sayı nasıl takvim oldu?
POSIX tanımına göre Unix zamanı, "Epoch"tan bu yana geçen saniyeyi verir ve her günü tam 86.400 saniye sayar (Open Group, bölüm 4.16). Epoch, 1 Ocak 1970 00:00:00 UTC. Bu tarihin özel bir anlamı yok. Wikipedia, Unix mühendislerinin onu "çalışması kolay bir tarih" olduğu için seçtiğini aktarıyor. İlk sürümlerde durum farklıydı: sistem saniyenin altmışta birini sayan 32 bitlik bir sayaç kullanıyordu ve bu sayaç yaklaşık iki yıl üç ayı taşıyabiliyordu. Taşmayı önlemek için başlangıç tarihi kaydırıldı, 1971 ve 1972 de denendi, sonunda sayım tam saniyeye çevrildi.
$ date +%s # şimdiki zaman, saniye cinsinden
$ date -u -d @0 # GNU date: sayıdan tarihe
Thu Jan 1 00:00:00 UTC 1970
$ date -u -d @-2147483648 # negatif sayı, 1970 öncesi
Fri Dec 13 20:45:52 UTC 1901macOS ve BSD sistemlerinde -d @sayı yerine -r sayı kullanılıyor. Komutların çıktısını kendi makinemde çalıştırarak doğruladım.

O dönemin makinelerinde "sayı" kelimesi bugünkünden çok daha fiziksel bir şeydi: Panelde adres ve veri satırlarının ışıkları yanıp sönüyor, bir sayının genişliği bir sıra ışığın uzunluğuyla ölçülüyordu. Bana kalırsa 2038 sorununu anlamak için bu görüntü iyi bir başlangıç. Sayaç ne kadar geniş yapılırsa o kadar ileri sayıyor, ve bir noktada sıra bitiyor.
2038'de ne taşıyor?
Unix zamanını işaretli 32 bitlik bir tam sayıda tutarsanız tavan 2³¹ − 1, yani 2.147.483.647. Bu sayı 19 Ocak 2038'de 03:14:07 UTC'ye denk geliyor. Bir saniye sonra sayaç en küçük değere, −2³¹'e dönüyor ve onu tarih sanan bir program 13 Aralık 1901 20:45:52 UTC'yi görüyor (Wikipedia). Aynı davranışı birkaç satırda görmek mümkün:
import struct, datetime
t = 2**31 # 03:14:08 UTC, 19 Ocak 2038
taşmış = struct.unpack('<i', struct.pack('<I', t))[0]
print(taşmış) # -2147483648
print(datetime.datetime.fromtimestamp(taşmış, datetime.timezone.utc))
# 1901-12-13 20:45:52+00:00
- 2.147.483.647 işaretli 32 bitlik sayaç tavanı (19 Ocak 2038 03:14:07 UTC)
- ≈ 11 yıl 3 ay bugünden 2038'e kalan süre (23 Ekim 2026 itibarıyla)
- 7 Şubat 2106 aynı sayaç işaretsiz olsaydı gelecek tavan (06:28:15 UTC)
- ≈ 292 milyar yıl işaretli 64 bitlik sayacın tavanı (Wikipedia)
Risk nerede, kimde değil?
Telefonların ve dizüstü bilgisayarların büyük bölümü 64 bitlik zamanla çalışıyor. Asıl zorluk uzun yıllar çalışan 32 bitlik gömülü sistemlerde: yönlendiriciler, kameralar, araç denetim birimleri. Wikipedia'nın derlemesine göre bu cihazlar tarih hesabı ya da günlük kaydı yaptıklarında risk taşıyor, güncellenmeleri de zor ya da imkânsız olabiliyor. Yalnızca iki an arasındaki farkı ölçen sistemlerde ciddi bir sorun beklenmiyor.
2038'i beklemek de gerekmiyor. 2006'da AOLserver, bir milyar saniye sonrasına ayarlanmış bir zaman aşımı yüzünden 13 Mayıs'ta, 01:27:28 UTC'den sonra gelen isteklerde taşmaya takıldı. Ayarı düşürmek sorunu çözdü. Aynı kaynakta bitiş tarihi 2038'i geçen sertifikaların da 32 bitlik sistemlerde doğrulama hatası verebildiği yazıyor. Buradan çıkardığım ders şu: İleri tarihli bir değer hesaplayan her kod (sertifika, çerez, abonelik süresi) 2038'e yaklaşmadan önce o sınıra çarpabilir.
Düzeltme: sayaç genişliyor
Çözümün özü basit: Sayacı 64 bite çıkarmak. 64 bitlik sistemlerin çoğunda zaten böyle. Wikipedia'nın sıraladığına göre Linux çekirdeği 5.6'dan (2020) itibaren 32 bitlik mimarilerde de 64 bitlik time_t kullanabiliyor, glibc ise 2.34'ten (Ağustos 2021) beri _TIME_BITS=64 tanımlanınca bunu açıyor. Gnulib yazışmalarında 32 bitlik hedeflerde _FILE_OFFSET_BITS=64 değerinin de birlikte verilmesi gerektiği not ediliyor. Kendi kodunuzda şuna bakabilirsiniz:
#include <stdio.h>
#include <time.h>
int main(void) {
printf("time_t: %zu bayt\n", sizeof(time_t));
return 0;
}$ gcc -D_TIME_BITS=64 -D_FILE_OFFSET_BITS=64 t.c -o t
$ ./t
time_t: 8 bayt64 bitlik makinemde program bayraksız da 8 bayt veriyor. Bayraksız derlenen bir 32 bitlik hedefte çoğu zaman 4 bayt çıkar, sorun orada başlıyor. Zaman yalnızca time_t içinde de durmuyor: Dosya sistemleri, veritabanı sütunları ve ağ protokolleri kendi alanlarını taşıyor.
| Sistem veya tür | Sınır | Not |
|---|---|---|
| İşaretli 32 bit time_t | 19 Ocak 2038 | Eski 32 bit sistemler |
| İşaretsiz 32 bit time_t | 7 Şubat 2106 | 1970 öncesi tarihleri bozar |
| ext4 (128 bayttan büyük inode) | 2446 | Ek bitlerle genişletilmiş |
| XFS big timestamps | 2486 | Linux 5.10'dan beri |
| İşaretli 64 bit time_t | ≈ 292 milyar yıl | 64 bit sistemlerin çoğunda varsayılan |
Sayaç artık saniyeyi hiç saymadı
Unix zamanı her günü 86.400 saniye sayıyor, oysa UTC'de arada 86.401 saniyelik günler oluyor. Artık saniye eklenince Unix sayısı kendini tekrar ediyor: 1483228800, hem 31 Aralık 2016 23:59:60'a hem 1 Ocak 2017 00:00:00'a karşılık gelebiliyor. Artık saniyeyi aşan iki zaman damgasının farkı da bir saniye eksik çıkıyor (Wikipedia).
$ date -u -d @1483228800
Sun Jan 1 00:00:00 UTC 2017 # GNU date ":60" anını göstermezBu tablo değişiyor. Ağırlıklar ve Ölçüler Genel Konferansı (CGPM) 2022'de UT1 ile UTC arasındaki farkın üst sınırının "2035'te ya da öncesinde" artırılmasına karar vermişti (Karar 4). 13-15 Ekim 2026'da toplanan 28. CGPM ise işi öne çekti. 5 numaralı karar, kesintisiz UTC'nin 20 Mayıs 2027'de yürürlüğe gireceğini ve |UT1 − UTC| farkının üst sınırının 3.600 saniye (1 saat) olacağını söylüyor. Kararın gerekçe bölümünde, hiç uygulanmamış bir "negatif artık saniye"nin yüksek risk taşıdığı da yazıyor. Haberi Euronews da aktardı.
- 1970 Epoch — Unix zamanı 1 Ocak 1970 00:00:00 UTC'den sayıyor
- 2006 AOLserver taşması — Bir milyar saniyelik zaman aşımı sınırı erken aştı
- Ağu 2021 glibc 2.34 — 32 bitlik platformlarda 64 bit time_t seçeneği
- 2022 CGPM Karar 4 — Artık saniyenin 2035'te ya da öncesinde bırakılması hedefi
- 15 Eki 2026 CGPM Karar 5 — Kesintisiz UTC kararı, fark sınırı 3.600 saniye
- 20 May 2027 Kesintisiz UTC — Artık saniye eklenmesi sona eriyor
- 19 Oca 2038 32 bit sınırı — İşaretli 32 bitlik sayaç 03:14:07 UTC'de doluyor
İki konu neden karışıyor?
Bana kalırsa karışıklığın nedeni ikisinin de "zaman" etiketi taşıması. 2038 bir depolama sorunu: Sayı kaç bit? Artık saniye ise saatin tanımıyla ilgili: Bir gün kaç saniye? 64 bite geçen bir sistem artık saniyeyi hâlâ saymıyor, artık saniyeyi bırakan dünya da 32 bitlik bir sayacı genişletmiyor. Küçük bir ironi de var: Unix zamanı artık saniyeyi yok sayarak tasarlandı, UTC de yeni saniye eklemeyi bırakınca bu yok sayma 2027'den sonrası için yeni bir belirsizlik üretmeyecek. Bu bir çıkarım, kararın metninde yazmıyor. Geçmişte eklenmiş saniyeler ise tarihte duruyor, eski kayıtlardaki belirsizlik de duruyor.
Kendi projenizde Zaman damgasını veritabanında ya da bir dosya biçiminde 32 bitlik alanda tutuyorsanız, ileri tarihli kayıtlar (abonelik, sertifika, çerez ömrü) 2038'den çok önce sorun çıkarabilir. Alan genişliğine bir kez bakmak yeterli olabilir.
Telefonum ya da bilgisayarım 2038'de bozulur mu?
Modern 64 bitlik işletim sistemleri genelde 64 bitlik zaman kullanıyor. Asıl risk güncellenmeyen eski 32 bitlik cihazlarda ve 32 bitlik alan kullanan veri biçimlerinde. Belirli bir cihaz için üreticinin açıklamasına bakmak gerekir.
Sayacı işaretsiz yapsak sorun çözülür mü?
7 Şubat 2106'ya kadar erteler, ama 1970 öncesi tarihler negatif sayıyla gösterildiği için onları bozar.
Artık saniyenin bitmesi saatleri bir saat kaydıracak mı?
Hayır. Karar, UT1 ile UTC arasındaki farkın 3.600 saniyeye kadar büyümesine izin veriyor. Karar metni bunun yüzyıllarca sürecek bir süreklilik sağladığını söylüyor.
Kodun ve bilgisayarların tarihiyle ilgileniyorsanız şu yazı da hoşunuza gidebilir:
İlk bilgisayarlar bugünkü kodu anlar mıydı? Kodlamanın kısa tarihi — ENIAC'ın kablolarından saklı programa ve bugünkü dillere uzanan kısa bir tarih.
Kaynaklar
- Unix time, Wikipedia (erişim: 2026-10-23)
- Year 2038 problem, Wikipedia (erişim: 2026-10-23)
- The Open Group Base Specifications, 4.16 Seconds Since the Epoch (erişim: 2026-10-23)
- PDP-11, Wikipedia (erişim: 2026-10-23)
- BIPM, 28th CGPM (2026), Resolution 5: On the technical actions needed to ensure the continuity of UTC (erişim: 2026-10-23)
- BIPM, 27th CGPM (2022), Resolution 4 (erişim: 2026-10-23)
- Euronews, 16 Ekim 2026: küresel zaman kuralları değişiyor, artık saniye 2027'de bitiyor (erişim: 2026-10-23)
- Gnulib: glibc 2.34 _TIME_BITS=64 desteği üzerine yazışma (erişim: 2026-10-23)
Kapak görseli: Jason Scott · CC BY 2.0. Şema: özgün grafik.