Saat Dilimleri ve Zaman Damgaları
UTC saklama, saat dilimlerini dönüştürme ve mülakatçıların zaman damgaları hakkında sorduğu ince noktalar.
Saat Dilimleri ve Zaman Damgaları, CoddyKit'te ücretsiz bir SQL Interview Prep dersidir. Bu, 4 dersinin 4. dersidir. Aşağıdan dersin tamamını ücretsiz okuyabilir, sonra tarayıcıda yerleşik kod editörü ve 7/24 yapay zeka koçu ile uygulamalı olarak pratik yapabilirsin. Bu, SQL Interview Prep öğrenme yolunun bir parçasıdır ve ilerlemeniz web ve CoddyKit uygulaması arasında senkronize olur. SQL Interview Prep kursu toplamda 4 dersten oluşur.
Zaman Dilimleri Adayları Neden Zorlar
Zaman dilimleri, kendine güvenen adayların tökezlediği konulardır; bu nedenle mülakat yapanlar derinlemesine bilginizi ölçmek için bunları sorar. Temel soru her zaman şudur: "Bölgeler arasındaki zaman damgalarını nasıl saklar ve karşılaştırırsınız?"
Profesyonel yanıt bir işlev değil, bir uygulama disiplinidir: her şeyi UTC'de saklayın, yalnızca gösterim aşamasında sınırda yerel saate dönüştürün. Saklama modelini doğru kurduğunuzda sorguların çoğu basitleşir.
- timestamp ve timestamptz
- Saat dilimleri arasında dönüştürme
- Doğrunun kaynağı olarak UTC
timestamp ve timestamptz
PostgreSQL'de iki zaman damgası türü vardır; bunları karıştırmak mülakatlarda sık yapılan bir hatadır.
timestamp(saat dilimi olmadan): hiçbir saat dilimine bağlı olmayan bir duvar saati değeridir. Kendisine verilen değeri tam olarak saklar.timestamptz(saat dilimiyle): Dahili olarak UTC şeklinde saklanır; girişte oturumun saat diliminden dönüştürülür, çıkışta tekrar dönüştürülür.
Adına rağmen timestamptz bir saat dilimi saklamaz; UTC'de kesin bir anı saklar. Bu ayrıntı mülakat yapanları etkiler.
CREATE TABLE events (
id bigint,
occurred_at timestamptz -- recommended: an absolute instant
);UTC'de Saklayın, Sınırda Dönüştürün
Altın kural şudur: Anları UTC'de kalıcı olarak saklayın (timestamptz kullanın) ve yerel saat dilimine yalnızca kullanıcıya sunarken dönüştürün. Bu, yaz saati uygulamasıyla ilgili belirsizlikleri önler ve her yerde zamana göre doğru sıralama yapılmasını sağlar.
"Neden UTC?" diye sorulursa şöyle yanıtlayın: UTC'de yaz saati değişiklikleri yoktur; bu nedenle aynı duvar saati değeri yerel saatin aksine iki kez oluşmaz veya atlanmaz.
-- Display a UTC instant in a user's zone (Postgres)
SELECT occurred_at AT TIME ZONE 'America/New_York' AS local_time
FROM events;AT TIME ZONE'un İki Farklı Anlamı
AT TIME ZONE akıllı bir yapıdır ve giriş türüne bağlı olarak birbirinin tersi iki işlem yaptığı için sıkça hata kaynağı olur:
- Bir
timestamptz'ye uygulandığında mutlak anı o saat dilimine dönüştürür ve yalın birtimestamp(oradaki yerel saat) döndürür. - Yalın bir
timestamp'e uygulandığında, o yerel saati ilgili saat diliminde gerçekleşmiş olarak yorumlar ve birtimestamptzdöndürür.
Hangi yönde çalıştığını bilmek, işin püf noktasıdır.
-- timestamptz -> local wall clock (returns timestamp)
SELECT TIMESTAMPTZ '2024-03-01 12:00:00+00'
AT TIME ZONE 'Asia/Tokyo'; -- 2024-03-01 21:00:00
-- plain timestamp interpreted in a zone (returns timestamptz)
SELECT TIMESTAMP '2024-03-01 12:00:00'
AT TIME ZONE 'Asia/Tokyo'; -- 2024-03-01 03:00:00+00Geçerli Anı Alma
"Şimdi" işlevlerinizi iyi tanıyın. NOW() ve CURRENT_TIMESTAMP, Postgres'te bir timestamptz döndürür. Bunlar ifadenin değil, işlemin başlangıcındaki zamanı döndürür; bu fark uzun süren işlemlerde önemlidir.
UTC'yi açıkça kullanmak için dönüştürün: NOW() AT TIME ZONE 'UTC'. MySQL'de UTC_TIMESTAMP() doğrudan UTC verir.
SELECT
NOW() AS tx_start_tz,
NOW() AT TIME ZONE 'UTC' AS utc_walltime;Asıl Sorun Yaz Saati Uygulaması
Mülakatçılar DST'nin uç durumlarını çok sever. Saatler ileri alındığında yerel saatteki bir saat mevcut değildir; saatler geri alındığında ise bir saat tekrarlanır. Yerel saati depolamak bu değerleri belirsiz veya geçersiz hâle getirir.
UTC depolamak bu sorunu tamamen ortadan kaldırır: her an benzersizdir ve sıralı olarak ilerler. 'America/New_York' gibi bir bölge adı kullanmak (-05:00 gibi sabit bir saat farkı kullanmamak), veritabanının her tarih için DST kurallarını doğru uygulamasını sağlar.
-- Region name applies DST automatically for the given date
SELECT TIMESTAMPTZ '2024-07-01 12:00:00+00'
AT TIME ZONE 'America/New_York' AS summer, -- EDT (-04)
TIMESTAMPTZ '2024-01-01 12:00:00+00'
AT TIME ZONE 'America/New_York' AS winter; -- EST (-05)Saat Dilimleri Arasında Yerel Güne Göre Gruplama
Gerçekçi bir sorun: "her kullanıcının yerel saatine göre günlük aktif kullanıcılar." UTC zaman damgasını doğrudan keserseniz UTC dışındaki kullanıcılar için gece yarısı sınırları yanlış olur.
Güne kesmeden önce zamanı kullanıcının saat dilimine dönüştürün. Dönüştürme, yerel saat sınırlarının hizalanması için yerel saati kaydırır.
SELECT
DATE_TRUNC('day', occurred_at AT TIME ZONE u.tz) AS local_day,
COUNT(DISTINCT e.user_id) AS dau
FROM events e
JOIN users u ON u.id = e.user_id
GROUP BY 1
ORDER BY 1;Zaman Damgalarını Güvenle Karşılaştırma
Bir timestamptz sütununa göre filtreleme yaparken açıkça belirtilmiş bir anla, tercihen bir UTC sabitiyle veya kayma içeren bir timestamptz ile karşılaştırın. Yalın bir dizeyle karşılaştırma, değerin öngörülemeyen oturum saat diliminde yorumlanmasına neden olabilir.
Bu sayede sorguyu kimin çalıştırdığından bağımsız olarak karşılaştırma belirsizliğini korumaz.
SELECT *
FROM events
WHERE occurred_at >= TIMESTAMPTZ '2024-03-01 00:00:00+00'
AND occurred_at < TIMESTAMPTZ '2024-04-01 00:00:00+00';Epoch ve Unix Zaman Damgaları
Birçok sistem zamanı Unix epoch'u olarak depolar (1970-01-01 UTC'den bu yana geçen saniyeler). Mülakatçı size bir tamsayı sütunu verip bunu okumanızı isteyebilir.
- Postgres:
TO_TIMESTAMP(epoch_seconds)birtimestamptzdöndürür. - Epoch'a geri dönüş:
EXTRACT(EPOCH FROM occurred_at). - MySQL:
FROM_UNIXTIME()veUNIX_TIMESTAMP().
Epoch değerleri doğaları gereği UTC'dir; depolama için popüler olmalarının nedenlerinden biri de budur.
SELECT
TO_TIMESTAMP(1709294400) AS as_ts, -- from epoch
EXTRACT(EPOCH FROM NOW())::bigint AS as_epoch; -- to epochFarklı SQL Lehçelerinde Saat Dilimi Notları
Her ortamda konuya hâkim görünmenizi sağlayacak kısa bir özet:
- Postgres:
timestamptz+AT TIME ZONE; en kapsamlı destek buradadır. - MySQL:
TIMESTAMP, oturumdakitime_zonearacılığıyla otomatik dönüştürülür;CONVERT_TZ(t, from, to)açıkça dönüştürme yapar.DATETIMEsaat dilimi bilgisine sahip değildir. - SQL Server:
datetimeoffsetbir saat farkını depolar;AT TIME ZONE 'name', Windows saat dilimi adlarını kullanarak dönüştürme yapar.
-- MySQL explicit conversion
SELECT CONVERT_TZ(event_dt, 'UTC', 'Europe/Istanbul') AS local_dt
FROM events;Gece Yarısını Aşan Oturumlara İleri Bir Örnek
İnce bir raporlama sorusu: bir oturum gece yarısını aşabildiğinde, oturumları yerel takvim gününe göre nasıl sayarsınız? Çözüm aynı disipline dayanır: yerel saate dönüştürün, ardından günlere ayırın.
Başlangıç ve bitiş zamanlarını timestamptz olarak depolayın; raporlama için yerel günü dönüştürülmüş başlangıçtan çıkarın. Bir oturumun iki güne bölünmesi gerekiyorsa gün dizisiyle birleştirme yapmanız gerekir; bu, devam sorusu olarak gündeme getirmek için iyi bir noktadır.
SELECT
DATE_TRUNC('day', started_at AT TIME ZONE 'Europe/Istanbul') AS local_day,
COUNT(*) AS sessions
FROM sessions
GROUP BY 1
ORDER BY 1;Kısa Kontrol
Önerilen depolama stratejisini ve nedenini doğrulayın.
Özet: Saat Dilimleri ve Zaman Damgaları
Aklınızda kalması gereken yaklaşım:
- UTC'yi depolayın ve
timestamptzkullanın; yalnızca görüntüleme sırasında adlandırılmış bir saat dilimine dönüştürün. - Adına rağmen
timestamptzbir saat dilimini değil, UTC'deki bir anı depolar. AT TIME ZONE, giriş türüne bağlı olarak her iki yönde çalışır: bir timestamptz değerini yerel saate dönüştürür veya yalın bir timestamp değerini bir saat diliminde gerçekleşmiş olarak yorumlar.- DST'nin otomatik uygulanması için bölge adlarını (
'America/New_York') kullanın; sabit saat farklarından kaçının. - Güne kesmeden önce yerel saate dönüştürün ve sütunları açıkça belirtilmiş UTC anlarıyla karşılaştırın.
Sıkça Sorulan Sorular
“Saat Dilimleri ve Zaman Damgaları” dersi ücretsiz mi?
Evet — “Saat Dilimleri ve Zaman Damgaları” dersin tüm metni burada web'de ücretsiz olarak okunabilir. Etkileşimli olarak pratik yapmak (yerleşik kod editörü ve 7/24 yapay zeka koçu) ve SQL Interview Prep kursunun geri kalanını açmak için CoddyKit PRO'ya yükselt. SQL Interview Prep kursu toplamda 4 dersten oluşur.
“Saat Dilimleri ve Zaman Damgaları” dersinde ne öğreneceğim?
UTC saklama, saat dilimlerini dönüştürme ve mülakatçıların zaman damgaları hakkında sorduğu ince noktalar. SQL Interview Prep ile uygulamalı kodu tarayıcıda doğrudan çalıştırarak pratik yaparsın ve 7/24 yapay zeka koçu dersi çalışırken sorularını yanıtlar.
SQL Interview Prep öğrenmeye başlamak için deneyim gerekli mi?
Önceden deneyim gerekmez. CoddyKit'te SQL Interview Prep, başlangıçtan ileri seviyeye kadar yapılandırıldığı için buradan başlayabilir veya başından başlayıp kendi hızında ilerleme yapabilirsin. Bu, 4 dersinin 4. dersidir.
“Saat Dilimleri ve Zaman Damgaları” dersi ne kadar sürer?
Çoğu CoddyKit dersi yaklaşık 5–10 dakika sürer. Her biri kısa ve etkileşimli olduğu için sabit ilerleme yaparsın ve web ile uygulama arasında tam olarak bıraktığın yerden devam edebilirsin.
Bu SQL Interview Prep dersinde kod yazıp çalıştırabilir miyim?
Evet. Her SQL Interview Prep dersi yerleşik bir kod editörü içerir, bu sayede tarayıcıda gerçek kod yazıp çalıştırabilir ve anlık yapay zeka geri bildirimi alırsın — yerel kurulum gerekli değildir.
Bu kursun tüm dersleri
- Tarih Aritmetiği ve Aralıklar
- Tarihleri Kırpma ve Gruplama
- Dizeleri Ayrıştırma ve Biçimlendirme
- Saat Dilimleri ve Zaman Damgaları