Təsəvvür elə, sənin aviabilet bronlama app-ın var. Reys Nyu-Yorkdan yerli vaxtla 10:00-da uçur və Londona yerli vaxtla 22:00-da çatır. Zaman zonalarını nəzərə almasan, serverin tam xaosa çevrilə bilər və yanlış eniş vaxtı göstərə bilər.
Zaman zonaları — sənin ən yaxın dostların (ya da hər şey tərsinə gedəndə ən pis düşmənin). Əgər istifadəçilərin müxtəlif ölkələrdədirsə və ya cədvəllərlə işləyirsənsə, hansı ki, yerli vaxta bağlıdır (məsələn, reys vaxtları və ya tədbir cədvəlləri), onda zaman zonalarını nəzərə almaq kritik dərəcədə vacib olur.
Zaman tipli verilənlər
Artıq danışmışdıq ki, zaman möhürləri ilə işləmək üçün iki data tipi var:
TIMESTAMP: tarix və vaxt zaman zonası nəzərə alınmadan.TIMESTAMPTZ: tarix və vaxt zaman zonası ilə birlikdə.
Gəlin bunları bir də nümunə ilə baxaq.
-- İki sütunlu cədvəl yaradırıq: TIMESTAMP və TIMESTAMPTZ
CREATE TABLE flight_schedule (
flight_id SERIAL PRIMARY KEY,
departure_time TIMESTAMP,
departure_time_with_tz TIMESTAMPTZ
);
-- Məlumat əlavə edirik
INSERT INTO flight_schedule (departure_time, departure_time_with_tz)
VALUES
('2023-10-25 10:00:00', '2023-10-25 10:00:00+00');
-- Məlumatı yoxlayaq
SELECT * FROM flight_schedule;
Nəticə serverinin zaman zonasından asılı olacaq. Məsələn:
| flight_id | departure_time | departure_time_with_tz |
|---|---|---|
| 1 | 2023-10-25 10:00:00 | 2023-10-25 10:00:00+00 |
Əsas fərq:
departure_timesütunu sadəcə tarix və vaxtı saxlayır, heç bir zaman zonasına bağlı deyil.departure_time_with_tzsütunu isə tarix və vaxtı zaman zonası ilə birlikdə saxlayır (+00bu nümunədə).
Zamanı fərqli zaman zonalarına çevirmək
PostgreSQL-də zaman zonaları ilə işləmək üçün AT TIME ZONE funksiyasından istifadə olunur.
UTC-ni lokal vaxta çevirmək
Tutaq ki, UTC formatında zaman möhürümüz var (beynəlxalq koordinasiyalı vaxt). Onu America/New_York zaman zonasındakı istifadəçiyə göstərmək istəyirik.
SELECT
'2023-10-25 14:00:00+00'::TIMESTAMPTZ AT TIME ZONE 'America/New_York' AS local_time;
Nəticə:
| local_time |
|---|
| 2023-10-25 10:00:00 |
AT TIME ZONE burada sanki sehrli çubuq kimidir: vaxtı UTC-dən göstərilən zaman zonasına çevirir.
Lokal vaxtı UTC-yə çevirmək
İndi isə əks tapşırıq: America/New_York zaman zonasındakı vaxtı UTC-yə çevirmək istəyirik.
SELECT
'2023-10-25 10:00:00'::TIMESTAMP AT TIME ZONE 'America/New_York' AS utc_time;
Nəticə:
| utc_time |
|---|
| 2023-10-25 14:00:00+00 |
Diqqət elə, nəticə TIMESTAMPTZ formatında olacaq, çünki zaman zonası (bu halda UTC) haqqında məlumatı da saxlayır.
TIMESTAMPTZ data tipi ilə işləmək
TIMESTAMPTZ ilə işləyəndə, PostgreSQL avtomatik olaraq serverinin (və ya sənin təyin etdiyin) zaman zonasını nəzərə alır.
Cari sessiya üçün zaman zonasını belə təyin edə bilərsən:
SET TIMEZONE = 'Europe/Istanbul';
Bundan sonra bütün TIMESTAMPTZ əməliyyatları bu zaman zonası ilə işləyəcək.
Nümunə: məlumat əlavə etmək və seçmək
-- Zaman zonasını təyin edirik
SET TIMEZONE = 'Europe/Istanbul';
-- Məlumat əlavə edirik
INSERT INTO flight_schedule (departure_time_with_tz)
VALUES ('2023-10-25 10:00:00+00');
-- Məlumatı yoxlayaq
SELECT departure_time_with_tz FROM flight_schedule;
Europe/Istanbul zaman zonasında nəticə:
| departure_time_with_tz |
|---|
| 2023-10-25 13:00:00+03 |
PostgreSQL vaxtı UTC-dən sənin göstərdiyin zaman zonasına avtomatik çevirir.
Praktiki nümunələr
Cədvəllər üçün zaman zonalarını nəzərə almaq. Tutaq ki, reys cədvəli olan bir cədvəlimiz var və hər qeyd UTC-də saxlanılır. Hər reys üçün çıxış vaxtını istifadəçinin lokal vaxtında göstərmək istəyirik.
SELECT
flight_id,
departure_time_with_tz AT TIME ZONE 'America/New_York' AS local_time
FROM flight_schedule;
Fərqli zaman zonalarından olan zaman məlumatlarını müqayisə etmək. Təsəvvür elə, iki hadisəni müqayisə edirik, biri bir şəhərdə, digəri başqa şəhərdə baş verib. PostgreSQL bunu avtomatik olaraq vahid zaman zonasına çevirib müqayisə etməyə imkan verir.
SELECT
'2023-10-25 10:00:00+03'::TIMESTAMPTZ > '2023-10-25 07:00:00+00'::TIMESTAMPTZ AS event_one_later;
Nəticə:
| event_one_later |
|---|
| t |
Müqayisə true qaytardı, çünki 10:00+03 əslində 07:00+00-a bərabərdir.
Məsləhətlər və tez-tez rast gəlinən problemlər
Zamanla işləmək — hiyləgər işdir. Bax, tez-tez nə baş verir:
TIMESTAMPəvəzinəTIMESTAMPTZistifadə etmirlər və sonra təəccüblənirlər ki, vaxt niyə düz gəlmir — çünki zaman zonaları sadəcə nəzərə alınmır.- Serverin hansı zaman zonasında işlədiyini bilmirlər və nəticədə məlumat bir vaxtda yazılır, başqa vaxtda oxunur.
AT TIME ZONEistifadə edəndə zaman zonasının adında səhv edirlər — və ya error alırlar, ya da səhv vaxt.
Belə problemlərə düşməmək üçün:
- Demək olar ki, həmişə
TIMESTAMPTZistifadə et, xüsusən də məlumat zaman zonasından asılıdırsa. - Vaxtı həmişə UTC-də saxla, istifadəçiyə göstərərkən isə lazım olan zaman zonasına çevir.
- Daha dərindən başa düşmək istəyirsənsə, bax PostgreSQL-in rəsmi vaxt və zaman zonası sənədi — çox faydalı şeydir.
GO TO FULL VERSION