MariaDB'de tarih ve saatle çalışmanın temeli üç adımdır: değeri doğru veri tipinde saklamak (DATE, DATETIME, TIMESTAMP), anlık zamanı NOW() veya CURDATE() ile almak, hesap ve gösterim için de DATE_ADD(), TIMESTAMPDIFF() ve DATE_FORMAT() gibi yerleşik fonksiyonları kullanmak. Saat dilimi ise time_zone sistem değişkeniyle yönetilir ve yalnızca TIMESTAMP sütunlarını dönüştürür.

Bu yazıda MariaDB 12.3 LTS dönemine ait resmî belgelerdeki tarih ve saat fonksiyonlarını sırasıyla ele alıyoruz: anlık zamanı alma, parçalara ayırma, biçimlendirme, metinden tarihe çevirme, tarih aritmetiği, iki tarih arasındaki farkı bulma, Unix zaman damgaları ve saat dilimleri. Veri tiplerinin depolama ayrıntıları için MariaDB veri tipleri yazısına bakabilirsiniz; burada fonksiyonların davranışına odaklanıyoruz.

Tarih ve saat veri tiplerine kısa bir bakış

Tarih ve saat veri tiplerine kısa bir bakış: DATE, TIME, DATETIME, TIMESTAMP

Tarihleri metin sütununda da saklayabilirsiniz, ancak belgeler bunun yerine zamana özgü tiplerin kullanılmasını önerir; çünkü yerleşik fonksiyonlar bu tiplerle doğru sonuç verir ve geçersiz değerler daha kolay yakalanır. DATE yalnızca tarihi (YYYY-MM-DD), TIME yalnızca süreyi veya saati (HHH:MM:SS, yani saat kısmı 24'ü aşabilir), DATETIME ikisini birlikte tutar. YEAR yalnızca yılı saklar.

TIMESTAMP görünüşte DATETIME'a benzer ama iki önemli farkı vardır. Birincisi aralıktır: belgelere göre MariaDB 11.5'ten itibaren 64 bit sistemlerde bu tip 1970-01-01 00:00:01 UTC ile 2106-02-07 06:28:15 UTC arasını kapsar (11.5 öncesinde üst sınır 2038'di). DATETIME ise 1000-01-01 00:00:00.000000 ile 9999-12-31 23:59:59.999999 arasını destekler. İkincisi saat dilimidir: TIMESTAMP değerleri yazılırken oturumun saat diliminden UTC'ye çevrilir, okunurken geri çevrilir; DATETIME ise olduğu gibi saklanır.

TipİçerikSaat dilimi dönüşümü
DATEYalnızca tarih (YYYY-MM-DD)Yok
TIMESaat veya süre (HHH:MM:SS)Yok
DATETIMETarih ve saat, 1000-9999 yıllarıYok, değer olduğu gibi saklanır
TIMESTAMPTarih ve saat, 1970-2106 (11.5 ve sonrası, 64 bit)Var, UTC olarak saklanır
YEARYalnızca yılYok

Her iki tip de 0 ile 6 arasında mikrosaniye hassasiyeti alabilir; hassasiyet yazılmazsa 0 kullanılır. Örneğin DATETIME(3) milisaniye düzeyinde değer tutar.

Anlık tarih ve saati almak: NOW, CURDATE, CURTIME, SYSDATE

Bugünün tarihi için CURDATE() ya da parantezsiz CURRENT_DATE, şu anki saat için CURTIME() ya da CURRENT_TIME kullanılır. Tarih ve saati birlikte almak için NOW() ve eş anlamlıları CURRENT_TIMESTAMP, LOCALTIME, LOCALTIMESTAMP vardır. Bu fonksiyonlar değeri geçerli saat diliminde döndürür; metin bağlamında YYYY-MM-DD HH:MM:SS, sayısal bağlamda YYYYMMDDHHMMSS.uuuuuu biçiminde görünür. İsteğe bağlı parametre mikrosaniye hassasiyetini belirler.

sql
SELECT NOW();
+---------------------+
| NOW()               |
+---------------------+
| 2010-03-27 13:13:25 |
+---------------------+

SELECT NOW() + 0;
+-----------------------+
| NOW() + 0             |
+-----------------------+
| 20100327131329.000000 |
+-----------------------+

SELECT CURRENT_TIMESTAMP(2);
+------------------------+
| CURRENT_TIMESTAMP(2)   |
+------------------------+
| 2018-07-10 09:47:26.24 |
+------------------------+

Belgeler MariaDB 11.7 ile gelen bir tip değişikliğine dikkat çeker: 11.7'den itibaren NOW() ve CURRENT_TIMESTAMP() SQL standardına uygun olarak bir TIMESTAMP değeri döndürür ve bu değer yaz saati geçişlerinde belirsizlik taşımaz. LOCALTIMESTAMP ise DATETIME döndürür; belgelerin uyarısına göre bu sonucu bir TIMESTAMP sütununa yazmak yaz saati geçişleri civarında veri kaybına yol açabilir.

NOW() ile SYSDATE() arasındaki fark özellikle önemlidir. NOW(), ifadenin çalışmaya başladığı anı döndürür ve aynı sorgu içinde kaç kez çağırırsanız çağırın sabit kalır; saklı bir yordam veya tetikleyici içinde ise yordamın ya da tetikleyen ifadenin başladığı anı verir. SYSDATE() ise çağrıldığı anı döndürür. Belgedeki örnekte iki saniyelik SLEEP(2) çağrısının iki yanında bu fark açıkça görülür:

sql
SELECT NOW(), SLEEP(2), NOW();
+---------------------+----------+---------------------+
| NOW()               | SLEEP(2) | NOW()               |
+---------------------+----------+---------------------+
| 2010-03-27 13:23:40 |        0 | 2010-03-27 13:23:40 |
+---------------------+----------+---------------------+

SELECT SYSDATE(), SLEEP(2), SYSDATE();
+---------------------+----------+---------------------+
| SYSDATE()           | SLEEP(2) | SYSDATE()           |
+---------------------+----------+---------------------+
| 2010-03-27 13:23:52 |        0 | 2010-03-27 13:23:54 |
+---------------------+----------+---------------------+

Tarihi parçalarına ayırmak

Bir tarihin yılını, ayını veya gününü ayrı ayrı almak için YEAR(), MONTH(), DAYOFMONTH() (kısaca DAY()) kullanılır. Saat tarafında HOUR(), MINUTE(), SECOND() vardır. DAYOFYEAR() yılın kaçıncı günü olduğunu (1-366), QUARTER() çeyreği (1-4) verir. Daha genel bir araç olarak EXTRACT(birim FROM değer), hem YEAR veya HOUR gibi tekil birimleri hem de YEAR_MONTH, HOUR_MINUTE gibi bileşik birimleri kabul eder; örneğin HOUR_MINUTE birimi 13:03 için 1303 gibi bir değer üretir.

Haftanın gününü veren iki fonksiyon sık karıştırılır, çünkü sayılandırmaları farklıdır:

FonksiyonPazartesiPazarAralık
DAYOFWEEK()211-7 (1 = Pazar)
WEEKDAY()060-6 (0 = Pazartesi)

Türkiye'de hafta pazartesi başladığı için WEEKDAY() genellikle daha sezgiseldir. Örneğin hafta sonu kayıtlarını bulmak için WEEKDAY(tarih) >= 5 koşulu cumartesi ve pazarı yakalar. Aynı işi DAYOFWEEK() ile yapmak isterseniz 1 ve 7 değerlerini kontrol etmeniz gerekir.

sql
SELECT siparis_id,
       YEAR(olusturma) AS yil,
       QUARTER(olusturma) AS ceyrek,
       WEEKDAY(olusturma) AS gun_no
FROM siparisler
WHERE EXTRACT(YEAR_MONTH FROM olusturma) = 202611;

DATE_FORMAT ile biçimlendirme ve Türkçe ay adları

DATE_FORMAT ile biçimlendirme ve Türkçe ay adları: %Y / %y, %m / %c, %d / %e, %H / %k

DATE_FORMAT(tarih, biçim[, yerel_ayar]) bir tarihi istediğiniz metin biçimine çevirir. Biçim dizesindeki % ile başlayan belirteçler tarihin parçalarıyla değiştirilir, geri kalan karakterler olduğu gibi kalır. Aynı belirteçler STR_TO_DATE() ve iki parametreli FROM_UNIXTIME() tarafından da kullanılır.

BelirteçAnlamı
%Y / %yDört / iki haneli yıl
%m / %cİki haneli ay / bir veya iki haneli ay
%d / %eİki haneli gün / bir veya iki haneli gün
%H / %k00-23 arası saat (iki hane) / 0-23 (tek hane)
%h, %I / %l01-12 arası saat / 1-12 (tek hane)
%iDakika (iki hane)
%s, %SSaniye (iki hane)
%fMikrosaniye (altı hane)
%W / %aTam / kısa gün adı (yerel ayara göre)
%M / %bTam / kısa ay adı (yerel ayara göre)
%jYılın günü (001-366)
%T / %r24 saatlik saat / 12 saatlik saat ve AM-PM
%Z / %zSaat dilimi kısaltması / +hhmm biçiminde fark (11.3.0 ve sonrası)
%%Düz % karakteri
sql
SELECT DATE_FORMAT('2009-10-04 22:23:00', '%W %M %Y');
+------------------------------------------------+
| DATE_FORMAT('2009-10-04 22:23:00', '%W %M %Y') |
+------------------------------------------------+
| Sunday October 2009                            |
+------------------------------------------------+

SELECT DATE_FORMAT('2007-10-04 22:23:00', '%H:%i:%s');
+------------------------------------------------+
| DATE_FORMAT('2007-10-04 22:23:00', '%H:%i:%s') |
+------------------------------------------------+
| 22:23:00                                       |
+------------------------------------------------+

Gün ve ay adlarının dili lc_time_names sistem değişkenine bağlıdır. Belgelere göre bu değişkenin varsayılanı, işletim sisteminin dil ayarından bağımsız olarak her zaman en_US'dir; yani ek ayar yapmazsanız adlar İngilizce gelir. Desteklenen yerel ayarlar listesinde Türkçe için tr_TR bulunur. Değişkeni oturum düzeyinde değiştirebilir ya da üçüncü parametreyle yerel ayarı doğrudan fonksiyona verebilirsiniz. Üç parametreli biçimin bir avantajı daha vardır: oturum ayarlarından bağımsız olduğu için belgelere göre sanal indeksli ve kalıcı üretilmiş (generated) sütunlarda kullanılabilir.

sql
SET lc_time_names = 'tr_TR';
SELECT DAYNAME(NOW()), MONTHNAME(NOW());

SELECT DATE_FORMAT(olusturma, '%e %M %Y, %W', 'tr_TR') AS okunur_tarih
FROM siparisler;

Metni tarihe çevirmek: STR_TO_DATE ve TO_DATE

Dışarıdan gelen 05.11.2026 gibi bir metni tarihe çevirmek için STR_TO_DATE(metin, biçim) kullanılır; bu fonksiyon DATE_FORMAT()'ın tersidir. Biçim dizesi hem tarih hem saat içeriyorsa DATETIME, yalnızca biri varsa DATE veya TIME döner. Metin biçime uymuyorsa sonuç NULL olur ve bir uyarı üretilir; bazı SQL modlarında (NO_ZERO_DATE, NO_ZERO_IN_DATE, ALLOW_INVALID_DATES) bu bir hataya da dönüşebilir.

sql
SELECT STR_TO_DATE('Wednesday, June 2, 2014', '%W, %M %e, %Y');
+---------------------------------------------------------+
| STR_TO_DATE('Wednesday, June 2, 2014', '%W, %M %e, %Y') |
+---------------------------------------------------------+
| 2014-06-02                                              |
+---------------------------------------------------------+

SELECT STR_TO_DATE('Wednesday23423, June 2, 2014', '%W, %M %e, %Y');
+--------------------------------------------------------------+
| STR_TO_DATE('Wednesday23423, June 2, 2014', '%W, %M %e, %Y') |
+--------------------------------------------------------------+
| NULL                                                         |
+--------------------------------------------------------------+
1 row in set, 1 warning (0.00 sec)

SELECT STR_TO_DATE('Wednesday23423, June 2, 2014', '%W%#, %M %e, %Y');
+----------------------------------------------------------------+
| STR_TO_DATE('Wednesday23423, June 2, 2014', '%W%#, %M %e, %Y') |
+----------------------------------------------------------------+
| 2014-06-02                                                     |
+----------------------------------------------------------------+

Son örnekteki %# belirteci, yalnızca STR_TO_DATE() için geçerli olan atlama belirteçlerinden biridir ve metindeki tüm rakamları atlar. %. noktalama işaretlerini, %@ harfleri atlar. Türkçe noktalı biçimi çevirmek için STR_TO_DATE('05.11.2026', '%d.%m.%Y') yazmanız yeterlidir. CSV gibi dosyalardan veri aktarırken bu dönüşümü yükleme sırasında yapmak için LOAD DATA ve mariadb-import yazısına bakın.

Belgelere göre MariaDB 12.3 ile Oracle uyumluluğu için TO_DATE() fonksiyonu da eklendi. Bu fonksiyon % belirteçleri yerine TO_CHAR() ile aynı Oracle tarzı biçim öğelerini (DD, MM, YYYY, HH24, MI gibi) kullanır, DATETIME döndürür ve dönüşüm hatasında kullanılacak varsayılan değeri belirtmek için DEFAULT ... ON CONVERSION ERROR sözdizimini kabul eder. Oracle'dan taşınan kodlarda işe yarar; yeni yazdığınız sorgularda STR_TO_DATE() daha yaygın ve 12.3 öncesi sürümlerle de uyumludur.

Tarih aritmetiği: DATE_ADD, DATE_SUB ve INTERVAL

Bir tarihe süre eklemenin en sağlam yolu DATE_ADD(tarih, INTERVAL miktar birim) fonksiyonudur. Belgelerin vurguladığı gibi gün, ay ve yıl sınırlarını, artık yılları kendisi hesaplar. Çıkarma için DATE_SUB() kullanabilir ya da DATE_ADD()'e eksi işaretli bir miktar verebilirsiniz. Aynı işlem + INTERVAL ve - INTERVAL operatörleriyle de yazılabilir.

sql
SELECT '2008-12-31 23:59:59' + INTERVAL 1 SECOND;
+-------------------------------------------+
| '2008-12-31 23:59:59' + INTERVAL 1 SECOND |
+-------------------------------------------+
| 2009-01-01 00:00:00                       |
+-------------------------------------------+

SELECT DATE_ADD('2010-12-31 23:59:59', INTERVAL 1 DAY);
+-------------------------------------------------+
| DATE_ADD('2010-12-31 23:59:59', INTERVAL 1 DAY) |
+-------------------------------------------------+
| 2011-01-01 23:59:59                             |
+-------------------------------------------------+

SELECT DATE_ADD('1900-01-01 00:00:00', INTERVAL '-1 10' DAY_HOUR);
+------------------------------------------------------------+
| DATE_ADD('1900-01-01 00:00:00', INTERVAL '-1 10' DAY_HOUR) |
+------------------------------------------------------------+
| 1899-12-30 14:00:00                                        |
+------------------------------------------------------------+

Birimler tekil (SECOND, MINUTE, HOUR, DAY, WEEK, MONTH, QUARTER, YEAR, MICROSECOND) veya alt çizgi içeren bileşik birimler olabilir. Bileşik birimlerde miktar bir metin olarak yazılır ve parçalar herhangi bir noktalama işaretiyle ayrılabilir: '2:30' HOUR_MINUTE iki saat otuz dakika, '2 6' DAY_HOUR iki gün altı saat, '1-2' YEAR_MONTH bir yıl iki ay anlamına gelir.

Sonucun tipi ilk parametreye ve birime göre değişir. İlk parametre DATETIME ise sonuç DATETIME olur. DATE değerine HOUR veya daha küçük bir birim eklerseniz sonuç DATETIME, DAY veya daha büyük bir birim eklerseniz DATE olur. İlk parametre zamana özgü bir tip değilse (örneğin düz bir metinse) fonksiyon metin döndürür. Bu kural, sonucu bir sütuna yazarken veya karşılaştırırken beklenmedik tip dönüşümlerini anlamanıza yardımcı olur.

İki tarih arasındaki fark: DATEDIFF ve TIMESTAMPDIFF

DATEDIFF(ifade1, ifade2), ilk tarihten ikincisini çıkarır ve sonucu gün olarak verir; saat kısmı hesaba katılmaz. TIMESTAMPDIFF(birim, ifade1, ifade2) ise ters sırayla çalışır, yani ikinci ifadeden birinciyi çıkarır ve sonucu seçtiğiniz birimde tam sayı olarak döndürür. Parametre sırasındaki bu fark en sık yapılan hatalardan biridir.

sql
SELECT DATEDIFF('2007-12-31 23:59:59','2007-12-30');
+----------------------------------------------+
| DATEDIFF('2007-12-31 23:59:59','2007-12-30') |
+----------------------------------------------+
|                                            1 |
+----------------------------------------------+

SELECT TIMESTAMPDIFF(MONTH,'2003-02-01','2003-05-01');
+------------------------------------------------+
| TIMESTAMPDIFF(MONTH,'2003-02-01','2003-05-01') |
+------------------------------------------------+
|                                              3 |
+------------------------------------------------+

SELECT TIMESTAMPDIFF(MINUTE,'2003-02-01','2003-05-01 12:05:55');
+----------------------------------------------------------+
| TIMESTAMPDIFF(MINUTE,'2003-02-01','2003-05-01 12:05:55') |
+----------------------------------------------------------+
|                                                   128885 |
+----------------------------------------------------------+

TIMESTAMPDIFF() bir tarih ile tarih-saat değerini karşılaştırabilir; tarih değeri gerektiğinde saat kısmı 00:00:00 kabul edilerek işlenir. Belgelerde yaş hesabı için önerilen kalıp TIMESTAMPDIFF(YEAR, dogum_tarihi, CURDATE()) biçimindedir ve doğum günü henüz gelmemişse bir eksik yıl döndürür, yani gerçek yaşı verir. DATEDIFF() sonucunu 365'e bölmek ise artık yıllar yüzünden yanlış sonuç verebilir.

Ay sonu, kırpma ve Unix zaman damgaları

LAST_DAY() verilen tarihin ayının son gününü döndürür ve şubat ayında artık yılı dikkate alır: LAST_DAY('2003-02-05') sonucu 2003-02-28, LAST_DAY('2004-02-05') sonucu 2004-02-29 olur. Geçersiz bir tarih verirseniz NULL ve bir uyarı alırsınız. MariaDB 12.2 ile gelen TRUNC(tarih[, biçim]) fonksiyonu ise bir tarihi güne, aya veya yıla kırpar ve DATETIME döndürür; aylık raporlarda dönem başını bulmak için kullanışlıdır.

sql
SELECT TRUNC('2025-09-24 12:43','MM');
+--------------------------------+
| TRUNC('2025-09-24 12:43','MM') |
+--------------------------------+
| 2025-09-01 00:00:00            |
+--------------------------------+

UNIX_TIMESTAMP() parametresiz çağrıldığında 1970-01-01 00:00:00 UTC'den bu yana geçen saniye sayısını verir. Bir tarih parametresi verirseniz sunucu bu tarihi geçerli saat diliminde yorumlar ve UTC'ye çevirerek saniyeye dönüştürür; yani aynı tarih metni farklı saat dilimine sahip oturumlarda farklı sayılar üretebilir. Ters dönüşüm FROM_UNIXTIME() ile yapılır. Belgelere göre 11.5'ten itibaren desteklenen en büyük değer 4294967295'tir (2106-02-07 06:28:15); bunun ötesindeki değerler NULL döndürür, bu nedenle daha ileri tarihler için DATETIME önerilir.

Saat dilimleri: time_zone, CONVERT_TZ ve saat dilimi tabloları

MariaDB üç saat dilimi ayarını izler: sunucunun genel saat dilimi, her oturumun kendi saat dilimi ve sunucu başlarken işletim sisteminden okunan sistem saat dilimi (system_time_zone). time_zone değişkeninin varsayılanı SYSTEM'dir, yani sistem saat dilimi kullanılır. Değişkene '+03:00' gibi UTC'ye göre bir fark ya da saat dilimi tabloları yüklüyse 'Europe/Istanbul' gibi adlandırılmış bir bölge verebilirsiniz.

sql
SHOW GLOBAL VARIABLES LIKE 'time_zone';
SET time_zone = '+03:00';
SET GLOBAL time_zone = 'Europe/Istanbul';

Kalıcı ayar için seçenek dosyasında bir sunucu grubuna default_time_zone satırı eklenir. SET GLOBAL yalnızca yeni bağlanan oturumları etkiler; her oturum değerini bağlandığı anda genel değerden devralır. Seçenek dosyalarının nerede bulunduğunu ve hangi sırayla okunduğunu MariaDB my.cnf yapılandırma dosyaları yazısında anlattık.

ini
[mariadb]
default_time_zone = 'Europe/Istanbul'

Adlandırılmış bölgeler için mysql veritabanındaki saat dilimi tablolarının dolu olması gerekir. Belgelere göre bu tablolar varsayılan olarak oluşturulur ama doldurulmaz. Linux'ta mariadb-tzinfo-to-sql aracı işletim sistemindeki zoneinfo verisini SQL'e çevirir; çıktı doğrudan mariadb istemcisine aktarılır. Tablolar doldurulduktan sonra sunucuyu yeniden başlatmanız önerilir. Saat dilimi kuralları zaman zaman değiştiği için tabloları da arada bir yeniden yüklemek gerekir.

bash
mariadb-tzinfo-to-sql /usr/share/zoneinfo | mariadb -u root mysql

CONVERT_TZ(değer, kaynak, hedef) bir tarih-saat değerini bir saat diliminden diğerine çevirir. Adlandırılmış bölgeler tablolar yüklü değilse çalışmaz ve fonksiyon NULL döndürür. Ayrıca değer, kaynak saat diliminden UTC'ye çevrildiğinde desteklenen TIMESTAMP aralığının dışına düşüyorsa hiçbir dönüşüm yapılmaz ve değer olduğu gibi döner:

sql
SELECT CONVERT_TZ('2016-01-01 12:00:00','+00:00','+10:00');
+-----------------------------------------------------+
| CONVERT_TZ('2016-01-01 12:00:00','+00:00','+10:00') |
+-----------------------------------------------------+
| 2016-01-01 22:00:00                                 |
+-----------------------------------------------------+

SELECT CONVERT_TZ('1969-12-31 22:00:00','+00:00','+10:00');
+-----------------------------------------------------+
| CONVERT_TZ('1969-12-31 22:00:00','+00:00','+10:00') |
+-----------------------------------------------------+
| 1969-12-31 22:00:00                                 |
+-----------------------------------------------------+

Saat dilimi ayarı NOW(), SYSDATE(), CURDATE(), CURTIME() ve UNIX_TIMESTAMP() sonuçlarını etkiler; UTC_DATE(), UTC_TIME() ve UTC_TIMESTAMP() ise etkilenmez. Veri tipleri tarafında yalnızca TIMESTAMP dönüştürülür. Belgeler bir de replikasyon uyarısı yapar: SYSTEM değeri ifade tabanlı ya da karma (mixed) günlükle kullanılıyorsa tüm replikalarda system_time_zone aynı olmalıdır, aksi halde TIMESTAMP sütunları doğru kopyalanmaz. Replikasyon kurulumunun ayrıntıları MariaDB replikasyon kurulumu yazısındadır.

Uygulamalı mini örnek: sipariş raporları

Aşağıdaki küçük tablo, oluşturma anını DATETIME olarak tutar ve varsayılan değer olarak CURRENT_TIMESTAMP kullanır; belgelere göre DATETIME sütunları bu varsayılanı kabul eder. Ardından son yedi günün siparişlerini, aylık toplamları ve teslim süresini hesaplayan üç sorgu geliyor. Bu sorgular belgelerdeki fonksiyonların doğrudan uygulamasıdır; tablo ve sütun adları bizimdir, bu yüzden çıktı göstermiyoruz.

sql
CREATE TABLE siparisler (
  siparis_id INT AUTO_INCREMENT PRIMARY KEY,
  tutar DECIMAL(10,2) NOT NULL,
  olusturma DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
  teslim DATETIME NULL
);

-- Son yedi gün
SELECT siparis_id, tutar
FROM siparisler
WHERE olusturma >= NOW() - INTERVAL 7 DAY;

-- Aylık toplam
SELECT DATE_FORMAT(olusturma, '%Y-%m') AS ay, SUM(tutar) AS toplam
FROM siparisler
GROUP BY DATE_FORMAT(olusturma, '%Y-%m');

-- Teslim süresi (saat)
SELECT siparis_id, TIMESTAMPDIFF(HOUR, olusturma, teslim) AS saat
FROM siparisler
WHERE teslim IS NOT NULL;

İlk sorguda koşulun sütunun kendisi üzerinde, fonksiyonun ise sabit tarafta durduğuna dikkat edin: olusturma >= NOW() - INTERVAL 7 DAY biçimi, olusturma üzerindeki bir indeksin kullanılmasına izin verir. Aynı koşulu DATEDIFF(NOW(), olusturma) <= 7 diye yazarsanız ifade her satır için ayrı hesaplanır. İndekslerin ayrıntıları için MariaDB index oluşturma, gruplama için GROUP BY ve toplama fonksiyonları yazılarına bakın.

Sık yapılan hatalar

Sık yapılan hatalar: DATEDIFF ile TIMESTAMPDIFF sırasını karıştırmak, Tarihleri metin sütununda tutmak, TIMESTAMP ile DATETIME farkını göz ardı etmek, Adlandırılmış saat dilimini...
  • DATEDIFF ile TIMESTAMPDIFF sırasını karıştırmak: DATEDIFF(a, b) a eksi b, TIMESTAMPDIFF(birim, a, b) b eksi a hesaplar. İşaretin ters çıkması bu yüzdendir.
  • Tarihleri metin sütununda tutmak: VARCHAR içindeki tarihler alfabetik sıralanır, geçersiz değerler fark edilmez ve her sorguda dönüşüm gerekir.
  • TIMESTAMP ile DATETIME farkını göz ardı etmek: Oturum saat dilimi değiştiğinde TIMESTAMP değerleri farklı görünür, DATETIME değerleri değişmez. Hangisinin size uygun olduğuna en başta karar verin.
  • Adlandırılmış saat dilimini tablolar boşken kullanmak: CONVERT_TZ() bu durumda sessizce NULL döndürür. Önce mariadb-tzinfo-to-sql ile tabloları doldurun.
  • Ay ve gün adlarının İngilizce gelmesine şaşırmak: lc_time_names varsayılanı her zaman en_US'dir; tr_TR ayarlayın ya da üçüncü parametreyi kullanın.
  • Sütunu fonksiyona sararak filtrelemek: WHERE YEAR(olusturma) = 2026 yerine WHERE olusturma >= '2026-01-01' AND olusturma < '2027-01-01' yazmak indeksin kullanılabilmesini sağlar.

Sık Sorulan Sorular

NOW() ile CURRENT_TIMESTAMP arasında fark var mı?

Hayır, belgelerde CURRENT_TIMESTAMP, LOCALTIME ve LOCALTIMESTAMP, NOW()'ın eş anlamlıları olarak listelenir. Tek ayrıntı, 11.7'den itibaren LOCALTIMESTAMP'ın DATETIME, NOW() ve CURRENT_TIMESTAMP()'ın ise TIMESTAMP tipinde değer döndürmesidir.

Türkiye saatini nasıl ayarlarım?

En basit yol oturumda SET time_zone = '+03:00'; yazmak ya da seçenek dosyasında default_time_zone değerini vermektir. Bölge adını (Europe/Istanbul) kullanmak isterseniz önce saat dilimi tablolarını mariadb-tzinfo-to-sql ile doldurmanız gerekir.

Yaşı veya kıdemi nasıl hesaplarım?

TIMESTAMPDIFF(YEAR, dogum_tarihi, CURDATE()) kalıbı tam yıl sayısını verir ve doğum günü henüz gelmediyse bir eksik sayar. Ay cinsinden kıdem için birimi MONTH yapmanız yeterlidir.

TRUNC ve TO_DATE gibi yeni fonksiyonlar her sürümde var mı?

Hayır. TRUNC() belgelere göre MariaDB 12.2'de, TO_DATE() ise 12.3'te geldi. Daha eski bir sunucu kullanıyorsanız bu fonksiyonlar bulunmaz; 12.x serisinin yeniliklerini MariaDB 12.3 LTS yenilikleri yazısında topladık.

Marka adları sahiplerine aittir. Bu yazı bağımsız bir teknik rehberdir; adı geçen kuruluşlarla bayilik veya ortaklık ilişkisi bulunduğu anlamına gelmez.

İlgili içerikler: MariaDB öğrenme rehberi · MariaDB veri tipleri · SELECT, WHERE, ORDER BY, LIMIT · GROUP BY ve toplama fonksiyonları · Event Scheduler ile zamanlanmış görevler · System-versioned temporal tablolar · SQL nedir