---
title: 'Tarih İşlevleri'
source: 'https://academia.sh/tr/kurslar/elektronik-tablolar/tarih-islevleri'
course: 'Elektronik Tablolarla Analiz'
language: tr
updated: '2026-08-17T18:08:42+00:00'
license: 'CC BY-SA 4.0'
---

# Tarih İşlevleri

Aynı 54 destek talebinin ortalama çözüm süresi üç gün sayma kararıyla 6,33, 7,33 ve 5,20 gün çıkıyor; uçlar hariç sayımda 6 talep sıfır gün sürmüş görünüyor, iş günü sayımında iki talep takvimde iki gün sürdüğü hâlde sıfır iş günü gösteriyor. Bir ay sonrasının ay sonunda ne demek olduğu 60 abonenin 6'sında ayrışıyor: kırpma kuralı üç aboneyi aynı güne toplayıp 28, 29 ve 30 günlük üç dönem üretiyor, taşma kuralı hepsine 31 gün veriyor ama Şubat okumasını Mart'a kaydırıyor. 54 açılış tarihinin 19'u metin olarak yazıldığında iki ayrı güne okunabiliyor ve en büyük sapma 323 gün.

Bir arıza kaydının açılışıyla kapanışı arasında kaç gün geçtiği basit bir çıkarma gibi görünür.
Değildir: çıkarma iki uç arasındaki **aralığı** verir, sorulan şey ise çoğu zaman **kapsanan gün
sayısıdır** ve ikisi bir gün farklıdır. Bu ders tarihin hücrede ne olduğunu kurar, aynı talep
kümesinin ortalama çözüm süresini üç kararla hesaplar ve "bir ay sonra" ifadesinin ay sonunda
iki ayrı tarih verdiğini gösterir.

- **TT16.** Tarih hücrede bir **sayıdır**: bir başlangıç gününden itibaren gün sayısı; bu modelde
  seri 1, 1 Ocak 2026'dır. Biçim yalnızca bir **görünüştür**.
- **TT17.** Destek talepleri ve okuma günleri kurgudur. Okuma günü ayın 1'i ile 31'i arasında
  dağıtılmıştır; ay sonu sorusunu yaratan budur.
- **TT18.** Hafta sonu iki gündür, tatil günü tanımlanmamıştır. `isgunu` iki ucu da dahil ederek
  hafta içi günleri sayar; tatil listesi eklenirse sayı yine değişir.

## Hücrede Duran Şey Bir Sayıdır

Aşağıdaki blok takvim çevrimini, okuma günlerini ve destek taleplerini kurar.

```js
// takvim.mjs — elektronik tablo MODELI: tarih hucrede bir SAYIDIR, bicim yalnizca gorunustur.
// Seri numarasi 1 = 1 Ocak 2026. Destek talepleri ve okuma gunleri kurgudur.
export const TOHUM = 20260602, TALEP = 54, SATIR = 60;
const uretec = (t) => { let s = t >>> 0;
  return () => (s = (s * 1664525 + 1013904223) >>> 0) / 4294967296; };

// Takvim cevrimi 2026-2027 icindir; iki yil da artik yil degildir, ikisi de 365 gundur.
const AY = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
const ONCE = AY.map((_, i) => AY.slice(0, i).reduce((a, b) => a + b, 0));
export const seri = (y, a, g) => (y - 2026) * 365 + ONCE[a - 1] + g;   // seri 1 = 1 Ocak 2026
export const tarihi = (s) => { let k = s - 1, y = 2026, a = 0;
  while (k >= 365) { k -= 365; y++; }               // ay sinirini asan gun sonraki aya tasar
  while (k >= AY[a]) k -= AY[a++];
  return [y, a + 1, k + 1]; };

const REF = /(\$?)([A-Z])(\$?)(\d+)/g;
export const kaydir = (f, dS, dR) => f.replace(REF, (_, a, s, b, r) =>
  (a ? "$" + s : String.fromCharCode(s.charCodeAt(0) + dS)) + (b ? "$" + r : String(+r + dR)));

const iki = (n) => String(n).padStart(2, "0");
const ISLEV = {
  tarih: (y, a, g) => seri(y, a, g),
  ay: (s) => tarihi(s)[1], gun: (s) => tarihi(s)[2],
  bicim: (s) => { const [y, a, g] = tarihi(s); return `${iki(g)}.${iki(a)}.${y}`; },
  aysonu: (s) => { const [y, a] = tarihi(s); return seri(a === 12 ? y + 1 : y,
    a === 12 ? 1 : a + 1, 1) - 1; },                 // sonraki ayin ilk gununden bir onceki
  haftagunu: (s) => ((seri(2026, 1, 1) + s - 1 + 3) % 7) + 1,   // 1 Ocak 2026 persembe
  enk: (a, b) => Math.min(a, b),
  isgunu: (b, k) => { let n = 0;
    for (let s = b; s <= k; s++) if (ISLEV.haftagunu(s) <= 5) n++;
    return n; },
};
export function deger(H, ad) {
  const v = H[ad];
  if (v === undefined) return 0;
  if (typeof v !== "string" || v[0] !== "=") return v;
  const ifade = v.slice(1).replace(REF, (m) => JSON.stringify(deger(H, m.replace(/\$/g, ""))));
  return Function(...Object.keys(ISLEV), `return (${ifade});`)(...Object.values(ISLEV));
}

export function sayfa() {
  const H = {}, r = uretec(TOHUM);
  H.A1 = "abone"; H.C1 = "tuketim"; H.T1 = "acilis"; H.U1 = "kapanis"; H.V1 = "okuma gunu";
  for (let i = 0; i < SATIR; i++) {
    const s = i + 2;
    H["A" + s] = "AB-" + String(1041 + i * 7).padStart(4, "0");
    r();                                    // 01'deki bolge sutunu: uretec ayni sirada calisir
    H["C" + s] = Math.round((2 + r() * r() * 78) * 10) / 10;
    H["V" + s] = 1 + (i * 7) % 31;          // okuma gunu ayin 1'i ile 31'i arasinda
  }
  // Destek talepleri: acilis 2026'nin ilk yarisinda, sure 0-20 gun.
  const z = uretec(TOHUM + 3);
  for (let i = 0; i < TALEP; i++) {
    const s = i + 2, b = seri(2026, 1, 1) + Math.floor(z() * 180);
    H["T" + s] = b;
    H["U" + s] = b + Math.floor(z() * z() * 21);
  }
  return H;
}

if (import.meta.url === `file://${process.argv[1]}`) {
  const H = sayfa();
  const g = (B) => (h) => h.map((v, j) => (j ? String(v).padStart(B[j])
    : String(v).padEnd(B[0]))).join("");
  const y = g([8, 10, 14, 10]);
  const o = (f) => deger({ ...H, X1: f }, "X1");
  console.log(y(["hucre", "acilis", "bicim(acilis)", "kapanis"]));
  for (const s of [2, 4, 5, 55])
    console.log(y(["T" + s, H["T" + s], o(`=bicim(T${s})`), H["U" + s]]));
  const F = Array.from({ length: TALEP }, (_, i) => H["U" + (i + 2)] - H["T" + (i + 2)]);
  console.log(`\n${TALEP} destek talebi. Ayni gun kapanan (fark 0): ` +
    `${F.filter((v) => v === 0).length}. Ham fark toplami ${F.reduce((a, b) => a + b, 0)} gun.`);
  console.log(`1 Ocak 2026 seri ${seri(2026, 1, 1)}, 31 Ocak 2026 seri ${seri(2026, 1, 31)}, ` +
    `28 Subat 2026 seri ${seri(2026, 2, 28)}; Subat 2026 ayinin son gunu ` +
    `${o("=bicim(aysonu(tarih(2026,2,1)))")}.`);
}
```

```
hucre       acilis bicim(acilis)   kapanis
T2              51    20.02.2026        57
T4              72    13.03.2026        89
T5             148    28.05.2026       159
T55             69    10.03.2026        69

54 destek talebi. Ayni gun kapanan (fark 0): 6. Ham fark toplami 342 gun.
1 Ocak 2026 seri 1, 31 Ocak 2026 seri 31, 28 Subat 2026 seri 59; Subat 2026 ayinin son gunu 28.02.2026.
```

`T2` hücresinde duran şey `20.02.2026` değil, `51`'dir; ikinci sütun ile üçüncü sütun aynı
hücrenin iki okunuşudur. **Bir hücrenin gösterdiği tarih, içindeki sayının bir yorumudur.**

Son satır ay sonu sorusunu kuruyor: Şubat 2026'nın son günü 28'dir, ayın 29, 30 ya da 31'inde
okunan sayaçların Şubat karşılığı yoktur.

## Üç Gün Sayma Kararı

Aynı 54 talep üç formülle ölçülür: birincisi uçları hariç tutar, ikincisi ikisini de sayar,
üçüncüsü yalnız hafta içi günleri sayar.

```js
// sure.mjs — ayni talep kumesi uc gun sayma karariyla: uclar haric, uclar dahil, is gunu.
import { sayfa, deger, kaydir, TALEP } from "./takvim.mjs";

const KARAR = [
  ["uclar haric", "=U2-T2"],
  ["uclar dahil", "=U2-T2+1"],
  ["is gunu (uclar dahil)", "=isgunu(T2,U2)"],
];
const H = sayfa();
const sutun = (f) => { const K = { ...H };
  for (let i = 0; i < TALEP; i++) K["W" + (i + 2)] = kaydir(f, 0, i);
  return Array.from({ length: TALEP }, (_, i) => deger(K, "W" + (i + 2))); };
const g = (B) => (h) => h.map((v, j) => (j ? String(v).padStart(B[j])
  : String(v).padEnd(B[0]))).join("");

const D = KARAR.map(([, f]) => sutun(f));
const y = g([24, 12, 12, 10]);
console.log(y(["W sutunu formulu", "toplam gun", "ortalama", "sifir"]));
KARAR.forEach(([ad], i) => { const d = D[i], t = d.reduce((a, b) => a + b, 0);
  console.log(y([ad, t, (t / TALEP).toFixed(2), d.filter((v) => v === 0).length])); });
console.log(`\n${TALEP} talep. Ortalama cozum suresi ` +
  KARAR.map(([ad], i) => `${(D[i].reduce((a, b) => a + b, 0) / TALEP).toFixed(2)} (${ad})`)
    .join(", ") + " gun.");

// Herhangi bir kararda sifir cikan talepler: sifir bir sure degil, bir sayma sonucudur.
const z = g([8, 14, 14, 12, 12, 10]);
console.log("\n" + z(["hucre", "acilis", "kapanis", "uclar haric", "uclar dahil", "is gunu"]));
const o = (f) => deger({ ...H, X1: f }, "X1");
for (let i = 0; i < TALEP; i++) if (D[0][i] === 0 || D[2][i] === 0)
  console.log(z(["W" + (i + 2), o(`=bicim(T${i + 2})`), o(`=bicim(U${i + 2})`),
    D[0][i], D[1][i], D[2][i]]));
```

```
W sutunu formulu          toplam gun    ortalama     sifir
uclar haric                      342        6.33         6
uclar dahil                      396        7.33         0
is gunu (uclar dahil)            281        5.20         2

54 talep. Ortalama cozum suresi 6.33 (uclar haric), 7.33 (uclar dahil), 5.20 (is gunu (uclar dahil)) gun.

hucre           acilis       kapanis uclar haric uclar dahil   is gunu
W14         10.06.2026    10.06.2026           0           1         1
W17         14.05.2026    14.05.2026           0           1         1
W26         19.01.2026    19.01.2026           0           1         1
W28         19.05.2026    19.05.2026           0           1         1
W49         06.03.2026    07.03.2026           1           2         0
W50         13.02.2026    14.02.2026           1           2         0
W51         06.05.2026    06.05.2026           0           1         1
W55         10.03.2026    10.03.2026           0           1         1
```

Rapor edilecek sayı ortalama çözüm süresidir ve üç değeri var: 6,33, 7,33 ve 5,20 gün. En
büyüğü ile en küçüğü arasındaki fark en küçük değerin yüzde 41'i kadar. Üçü de savunulabilir;
hangisinin kastedildiğini "ortalama çözüm süresi" ifadesi söylemiyor.

Sıfır sütunu kararın nerede kanadığını gösteriyor. Uçlar hariç sayımda 6 talep **sıfır gün**
sürmüş görünüyor; oysa o talepler açıldıkları gün kapandılar, yani bir gün sürdüler. Sıfırları
"anında çözüldü" diye okuyan bir rapor verinin değil, sayma kararının sonucunu yazar.

Alt tablonun son iki satırı ters yönde bir uç veriyor: `W49` ve `W50` takvimde iki gün sürdü,
tamamen hafta sonuna denk geldiği için **sıfır** iş günü gösteriyor. **Aynı kayıt üç sayma
kuralında üç ayrı süre taşır.**

## Bir Ay Sonra Ne Zamandır

"Bir ay" sabit bir gün sayısı değildir. Aşağıdaki blok Şubat okumasını iki kuralla hesaplar,
metne çevrilmiş tarihlerin belirsizliğini sayar ve gün sayma kararını dört yazımda tarar.

```js
// ay.mjs — "bir ay sonra" iki kuralla; ve gun sayma kararinin sayfada nerede durdugu.
import { sayfa, deger, kaydir, seri, TALEP, SATIR } from "./takvim.mjs";

const H = sayfa();
const o = (K, f) => deger({ ...K, X9: f }, "X9");
const g = (B) => (h) => h.map((v, j) => (j ? String(v).padStart(B[j])
  : String(v).padEnd(B[0]))).join("");
// Ocak okumasi ayin V. gunu; Subat okumasi "bir ay sonra". Iki kural iki tarih verir.
const KURAL = {
  kirpma: "=tarih(2026,2,enk(V2,gun(aysonu(tarih(2026,2,1)))))",
  tasma: "=tarih(2026,2,V2)",
};
const sutun = (K, c, n, f) => { const M = { ...K };
  for (let i = 0; i < n; i++) M[c + (i + 2)] = kaydir(f, 0, i);
  return Array.from({ length: n }, (_, i) => deger(M, c + (i + 2))); };
const OCAK = Array.from({ length: SATIR }, (_, i) => seri(2026, 1, H["V" + (i + 2)]));
const S = Object.fromEntries(Object.entries(KURAL).map(([a, f]) =>
  [a, sutun(H, "Y", SATIR, f)]));

const y = g([10, 8, 14, 10, 14, 10]);
console.log(y(["hucre", "okuma", "kirpma", "donem", "tasma", "donem"]));
for (const s of [2, 6, 15, 24]) { const i = s - 2;
  console.log(y(["V" + s, H["V" + s], o(H, `=bicim(${S.kirpma[i]})`), S.kirpma[i] - OCAK[i],
    o(H, `=bicim(${S.tasma[i]})`), S.tasma[i] - OCAK[i]])); }

const farkli = S.kirpma.filter((s, i) => s !== S.tasma[i]).length;
const kacan = S.tasma.filter((s) => o(H, `=ay(${s})`) !== 2).length;
console.log(`\n${SATIR} abonenin ${farkli} tanesinde iki kural farkli tarih veriyor ` +
  `(okuma gunu 29, 30 ya da 31 olanlar). Tasma kuralinda ${kacan} abonenin ` +
  `"Subat okumasi" Subat ayina dusmuyor.`);

// Metin olarak girilmis tarih: gun ile ay yer degistirebiliyorsa hucre iki gune okunur.
const ikili = Array.from({ length: TALEP }, (_, i) =>
  [H["T" + (i + 2)], o(H, `=ay(T${i + 2})`), o(H, `=gun(T${i + 2})`)])
  .filter(([, a, gn]) => gn <= 12 && gn !== a)       // gun 12'den buyukse yer degistiremez
  .map(([s, a, gn]) => Math.abs(seri(2026, gn, a) - s));
console.log(`${TALEP} acilis tarihinin ${ikili.length} tanesi "GG.AA.YYYY" metni olarak ` +
  `girildiginde iki ayri gune okunabiliyor; en buyuk sapma ${Math.max(...ikili)} gun.`);

// Geri okuma taramasi: gun sayma karari formul metninde nerede duruyor.
const P = { ...H, X1: "uc dahil (1/0)", X2: 1 };    // etiket solda, deger sagda
const YAZIM = [["=U2-T2", "yok"], ["=U2-T2+1", "gomulu sabit"],
  ["=U2-T2+$X$2", "parametre hucresi"], ["=isgunu(T2,U2)", "islev adi"]];
const z = g([16, 20, 10, 10, 10]), top = (d) => d.reduce((x, v) => x + v, 0);
console.log("\n" + z(["formul", "karar nerede", "toplam", "X2=0", "pesinden"]));
for (const [f, yer] of YAZIM) {
  const a = sutun(P, "W", TALEP, f), b = sutun({ ...P, X2: 0 }, "W", TALEP, f);
  console.log(z([f, yer, top(a), top(b), a.filter((v, i) => v !== b[i]).length]));
}
```

```
hucre        okuma        kirpma     donem         tasma     donem
V2               1    01.02.2026        31    01.02.2026        31
V6              29    28.02.2026        30    01.03.2026        31
V15             30    28.02.2026        29    02.03.2026        31
V24             31    28.02.2026        28    03.03.2026        31

60 abonenin 6 tanesinde iki kural farkli tarih veriyor (okuma gunu 29, 30 ya da 31 olanlar). Tasma kuralinda 6 abonenin "Subat okumasi" Subat ayina dusmuyor.
54 acilis tarihinin 19 tanesi "GG.AA.YYYY" metni olarak girildiginde iki ayri gune okunabiliyor; en buyuk sapma 323 gun.

formul                  karar nerede    toplam      X2=0  pesinden
=U2-T2                           yok       342       342         0
=U2-T2+1                gomulu sabit       396       396         0
=U2-T2+$X$2        parametre hucresi       396       342        54
=isgunu(T2,U2)             islev adi       281       281         0
```

Birinci tablo iki kuralın bedelini yan yana koyuyor. Kırpma kuralında ayın 29, 30 ve 31'inde
okunan üç abone 28 Şubat'a toplanıyor ve dönemleri 30, 29 ve 28 gün oluyor: aynı tarihte okunan
üç sayacın dönemi üç ayrı uzunlukta ve sayfada bunu söyleyen bir sütun yok. Taşma kuralında dönem
31 gün, ama Şubat okuması 1, 2 ve 3 Mart'a kayıyor: **6 abonenin Şubat okuması Şubat ayında
değil.**

Metin tarih satırı üçüncü bir belirsizlik ölçüyor. 54 açılışın 19'unda gün numarası 12'den
küçüktür; böyle bir tarih `GG.AA.YYYY` metni olarak yazıldığında ay ile gün yer değiştirebilir
ve hücre iki ayrı güne okunur — en büyük sapma 323 gün. **Metne çevrilmiş bir tarih geri
okunamaz bir karardır.**

Son tablo dersin ikinci sayısıdır. İlk iki yazım kararı sayfada tutmuyor: `=U2-T2` uçların
hariç tutulduğunu söylemez, `=U2-T2+1` bir `1` gösterir ama o `1`'in ne olduğunu söylemez.
Üçüncüde karar `X2` hücresindedir, etiketiyle iki adımda okunur ve değiştirildiğinde 54 hücre
peşinden gelir; dördüncüde karar işlevin adındadır. İlk ikisinin sonucu 342 ile 396; ikisi de
doğru, ikisi de kaynaksız.

## Özet

- Tarih hücrede bir sayıdır; biçim o sayının bir yorumudur ve içeriğini değiştirmez.
- Aynı 54 talebin ortalama çözüm süresi üç sayma kararıyla 6,33, 7,33 ve 5,20 gün çıktı;
  fark en küçük değerin yüzde 41'i kadar.
- Sıfır bir süre değil, bir sayma sonucudur: uçlar hariç sayımda 6 talep, iş günü sayımında
  hafta sonuna denk gelen 2 talep sıfır gösterdi.
- "Bir ay sonra" ay sonunda iki ayrı tarih verir: kırpma kuralı 28, 29 ve 30 günlük üç dönem
  üretti, taşma kuralı 31 gün verdi ama 6 abonenin Şubat okumasını Mart'a kaydırdı.
- Gün sayma kararı yalnız parametre hücresine ya da işlev adına yazıldığında geri okunur;
  gömülü `+1` sayıyı gösterir, kararı göstermez. Metne çevrilmiş 19 tarih hiç geri okunamaz.

## Sonraki Adım

Buraya kadar her formül aynı satıra bakıyordu. Oysa önceki ders bir şeyi varsaymıştı: ziyaret
kaydındaki kodun abone tablosunda **bulunması** ve karşılığındaki tüketimin **getirilmesi**. O
işi yapan şey bir arama işlevidir ve arama, kendisine verilen sütun numarasına ya da başlık
adına göre iki ayrı biçimde yazılabilir. İki biçim aynı sonucu verir; ta ki tablonun ortasına
bir sütun eklenene kadar. Sonraki ders bir sütun eklendiğinde kaç aramanın kırıldığını, kaçının
hata verdiğini ve kaçının hata vermeden yanlış değer döndürdüğünü sayar.
