Manage Data in Different Time Zones

MÜXTƏLIF  BÖLGƏLƏRDƏKI VAXTLARIN FUNKSIYALARLA IDARƏ OLUNMASI

Salam, bloguma xoş gəlmisiniz! Oracle SQL yazılarımın bugünkü mövzusuyla artıq tanış olmuşsunuzdur, elə isə başlayaq 🙂

ORACLE SQL lokal və uzaq(remote) vaxt zonalarının idarə edilməsi üçün bir çox xüsusiyətlərə malikdir.  Məsələn helpdesk-ə edilən müraciətlər fərqli ölkələrdən, zonalardan ola bilər və bu müraciətləri vaxtları ilə daha dəqiq şəkildə bazada saxlamaq lazımdır, Bunun üçün oracle sql-in bir neçə yararlı funksiyalarından və verilən tiplərindən istifadə edəcəyik.

ORACLE SQL – dəki bütün tranzaksiyalar 3 vaxt zonası ilə əlaqədardır.

  • UTC vaxtı – hansı ki Qrinviç meridianının orta Günəş vaxtıdır və digər vaxt zonaları bu vaxta görə hesablanır.
  • Verilənlər bazası vaxt zonası – Verilənlər bazasının yükləndiyi bölgənin vaxt zonasıdır(DBTIMEZONE funksiyası ilə baxa bilərsiniz)
  • Sessiya vaxt zonası – Verilənlər bazasına qoşulan istifadəçilərin sahib olduğu vaxt zonasıdır(SESSIONTIMEZONE funksiyası ilə baxa bilərsiniz)

Bu vaxt zonalarını DATETIMESTAMP tarix tipləri dəstəkləmir. Vaxt zonaları üçün istifadə edəcəyimiz verilən tipləri TIMESTAMP WITH TIME ZONETIMESTAMP WITH LOCAL TIME ZONE olacaq. Bu verilən tiplərinin fərqlərinə bu şəkildən baxa bilərsiniz.

BAZA vaxtı vs SESSIYA vaxtı (Database Time vs. Session Time)

  • Baza vaxt zonası DBTIMEZONE funksiyası ilə təyin edilir.
  • Sessiya vaxt zonası SESSIONTIMEZONE funksiyası ilə təyin edilir.
SELECT DBTIMEZONE, SESSIONTIMEZONE FROM DUAL;

DBTIMEZONE SESSIONTIMEZONE

———- ————————————

+00:00 America/New_York

Nəticəyə baxdığımız zaman DBTIMEZONE-un UTC+0, SESSIONTIMEZONE-un isə America/New_York olduğunu görürük.

DBTIMEZONE-u dəyişmək üçün: ALTER DATABASE SET TIME_ZONE = ‘Europe/Zurich’;

SESSIONTIMEZONE-u dəyişmək üçün:  ALTER SESSION SET TIME_ZONE = ‘America/Los_Angeles’;

Əgər baza vaxt zonasını dəyişdirdiyiniz zaman xəta ilə qarşılaşırsınızsa bu sizin bazada TIMESTAMP WITH LOCAL TIME ZONE verilən tipində cədvəllərinizin olduğu deməkdir. Bu sorğu ilə xətaya səbəb olan cədvəllərinizi tapa bilərsiniz.

SELECT OWNER, TABLE_NAME, COLUMN_NAME, DATA_TYPE

FROM DBA_TAB_COLUMNS

WHERE DATA_TYPE LIKE ‘%LOCAL TIME_ZONE%’

ORDER BY OWNER, TABLE_NAME, COLUMN_NAME;

 

UTC nədir?

Coordinated Universal Time və ya qısaca UTC, Greenwich Mean Time(GMT)-in “yeni” adıdır. Koordinasiya edilmiş ümumdünya vaxtıdır və  beynəlxalq olaraq vaxtın ölçülmə standartıdır. UTC və GMT arasında fərqlər mövcuddur ancaq bu fərqlər bizim bazadakı işlərimizə təsir etmir. Digər dünya ərazilərindəki vaxtlar yerləşim yerinə görə UTC+offset şəklində bir dəyər alır. Məsələn bu dəyər Bakı üçün UTC/GMT + 04:00-dür.

SQL dünyasında önəmlilik dərəcəsinə görə birinci UTC-ə daha sonra database server(DBTIMEZONE) vaxtına sonra isə client system(SESSİONTIMEZONE)-a önəm verilir.

Vaxt Zonası Region Adları

UTC sistemində mövcud olan müxtəlif region adlarıdır.Hər birinin mətn formasında adı və qısaltması vardır.

  • Central Daylight Time (UTC-5)
  • Central Standard Time (UTC-6)
  • Eastern Standard Time (UTC-5)
  • Local Mean Time (UTC-6)

Bu şəkildə bir neçə region adları və qısaltmaları verilib.

Bundan əlavə əgər bazanızda olan bütün vaxt zonaları adlarına baxmaq istəyirsinizsə bu sorğudan istifadə edə bilərsiniz.

SELECT TZABBREV, TZNAME FROM V$TIMEZONE_NAMES ORDER BY TZABBREV, TZNAME;

VAXT ZONASI VERİLƏN TİPLƏRİ

ORACLE SQL-də 2 verilən tipi vardır ki,  müxtəlif vaxt zonalarında olan vaxtları idarə etmək üçün istifadə olunur.

  • TIMESTAMP WITH TIME ZONE
  • TIMESTAMP WITH LOCAL TIME ZONE

TIMESTAMP WITH TIME ZONE

TIMESTAMP WITH TIME ZONE verilən tipi ORACLE SQL-in TIMESTAMP tipində oxşardır. TIMESTAMP tipinə əlavə olaraq TIMEZONE_HOUR, TIMEZONE_MINUTE, TIMEZONE_REGION, TIMEZONE_ABBR dəyərlərini əlavə edir.

Saxladığı məlumatı 2 cür saxlaya bilir.

  • Vaxt zonası region adı ilə
  • Vaxt zonası offset(UTC və lokal vaxt arasındakı interval)-i ilə

Oracle tövsiyə edirki vaxt zonaları ilə əlaqədar məlumatlarınızı vaxt zonası region adı ilə saxlamağa üstünlük verin.

TIMESTAMP WITH LOCAL TIME ZONE

TIMESTAMP WITH LOCAL TIME ZONE verilən tipi ORACLE SQL-in TIMESTAMP tipinə oxşardır. TIMESTAMP WITH TIME ZONE-dan fərqli olaraq vaxt zonasını saxlamır(doesnt store) və hər zaman qaytardığı məlumat istifadəçinin yerləşdiyi vaxt zonasının dəyəri olur.

VAXT ZONASI FUNKSİYALARI

CURRENT_DATE, CURRENT_TIMESTAMP

Cari gün və cari gün+saatı+vaxt sonasını qaytarır.

SELECT CURRENT_DATE, CURRENT_TIMESTAMP FROM DUAL;

CURRENT_DATE CURRENT_TIMESTAMP

————————- ———————————-

20-NOV-15 20-NOV-15 11.12.50.843000 +04:00

LOCALTIMESTAMP

LOCALTIMESTAMP istifadəçinin lokal sessiya vaxtını TIMESTAMP şəklində qaytarır.

SELECT LOCALTIMESTAMP(4) FROM DUAL;

LOCALTIMESTAMP(4)

—————————————

18-NOV-15 11.15.20.031300 AM

SYSTIMESTAMP

SYSTIMESTAMP bazanın əməliyyat sisteminin  vaxtını TIMESTAMP WITH TIME ZONE şəklində qaytarır.

SELECT SYSTIMESTAMP FROM DUAL;

SYSTIMESTAMP

————————————

18-NOV-15 12.21.27.437000000 AM -04:00

NEW_TIME

NEW_TIME(d,t1,t2)

d – DATE tipindədir.

t1, t2 – vaxt zonası göstəriciləridirlər. Bu şəkildə ətraflı göstərilib.

Verilmiş DATE tipindəki d-dəyərini t1 və t2 dəyərlərinə əsasən yeni tarixə çevirir, t1 verilmiş d-dəyərinin aid olduğu vaxt zonasıdır.NEW_TIME funksiyası d-dəyərini t2 vaxt zonasına çevirəcək.

SELECT TO_CHAR(NEW_TIME(TO_DATE('2015-NOV-20 12:55:56','RRRR-MON-DD HH24:MI:SS'),'AST','HST'),'DD-MON-RR HH:MI:SS') NEW_DATE FROM DUAL;

NEW_DATE

————————-

20-NOV-15 06:55:56

FROM_TZ

FROM_TZ(ts, tz)

tsTIMESTAMP tipindədir.

tz – vaxt zonasının UTC qarşılığıdır.

Verilmiş TIMESTAMP dəyərini(ts) vaxt zonası ilə birlikdə TIMESTAMP WITH TIME ZONE tipində qaytarır.

 SELECT FROM_TZ( TIMESTAMP '2015-11-20 09:08:30', '+07:30') FROM DUAL;

FROM_TZ(TIMESTAMP’2015-11-2009:08:30′,’+07:30′)

——————————————————————–

20-OCT-15 09.08.30.000000000 AM +07:30

TO_TIMESTAMP_TZ

TO_TIMESTAMP_TZ(c, format_model)

c – char tipindədir

format_model – verilmiş c-dəyərinə uyğun format modelidir.

Verilmis char tipdə olan məlumatı TIMESTAMP WITH TIME ZONE tipinə çevirir.

SELECT TO_TIMESTAMP_TZ('20-11-2015 09:25:30','DD-MM-RRRR HH24:MI:SS') "Time" FROM DUAL;

Time

———————————————————

20-NOV-15 09.25.30.000000000 AM +04:00

CAST

CAST(e AS d)

d – verilən tipi

e – d verilən tipinə çevirmək istədiyimiz ifadə

Verilmis e ifadəsini d verilən tipinə çevrir.

SELECT CAST('20-NOV-15 10:07:30' AS TIMESTAMP WITH LOCAL TIME ZONE) "Converted " FROM DUAL;                                                                                         

Converted

————————————

20-NOV-15 10.07.30.000000000 AM

SELECT CAST(TO_TIMESTAMP('20-NOV-15 10:12:30','DD-MON-RR HH24:MI:SS') AS TIMESTAMP WITH LOCAL TIME ZONE) "Converted " FROM DUAL;

Converted

——————————

20-NOV-15 10.12.30.000000000 PM

EXTRACT

EXTRACT( fm FROM e)

fm – format model-dir. Bu şəkildə “keyword” adı altında olan modellərdən biridir. Məs: year, month, day, hour, minute, second, timezone_hour, timezone_minute, timezone_region, timezone_abbr

e – tarix tiplərindən biridir.

SELECT EXTRACT(MINUTE FROM TO_TIMESTAMP('2015-11-20 10:19:14','RRRR-MM-DD HH24:MI:SS')) "Minute" FROM DUAL;

Minute

———–

19

SYS_EXTRACT_UTC

SYS_EXTRACT_UTC(dtz)

dtz – özündə vaxt zonasını saxlayan hər hansı  tarix tipi.

Verilmis tarix tipindən UTC dəyərini xaric edi TIMESTAMP tipində dəyər qaytarır.                                                                                                        

SELECT SYS_EXTRACT_UTC(TIMESTAMP '2015-11-20 10:38:00 +04:00') "HQ" FROM DUAL;

HQ

——————————————

20-NOV-11 06.38.00.000000000 AM

AT TIME ZONE, AT LOCAL

Bu ifadələri bir misal üzərində anlatmaq istəyirəm. Birinci bazamızın və sessiyamızın hansı vaxt zonalarında olduğunu öyrənək.

SELECT DBTIMEZONE, SESSIONTIMEZONE FROM DUAL;

DBTIMEZONE   SESSIONTIMEZONE

—————–    —————————

-05:00               America/ Los_Angeles

İndi isə istifadəçi olaraq sessiya vaxtımızı baza vaxtına görə necə dəyişdiyinə baxaq.

SELECT TO_TIMESTAMP('2015-NOV-20 10:58:00','RRRR-MON-DD HH24:MI:SS') AT TIME ZONE DBTIMEZONE "DB Time" FROM DUAL;

DB Time

——————————————————–

20-NOV-15 01.58.00.000000000 PM -05:00

Normalda Los Angeles və Bakı arasında 12 saatlıq bir fərq var ancaq biz bu nəticədə 3 saatlıq bir fərq gördük çünki Los Angeles UTC-08:00 , Bakı isə UTC-05:00 vaxt zonalarına məxsusdur və ORACLE UTC -ə öncəlik verdiyini qeyd etmişdik yəni bu 3 saatlıq fərq məhz UTC-lər arasındakı fərqdir.

AT LOCAL

Başqa vaxt zonalarında olan tarix və saatların bizim yerləşdiyimiz vaxt zonasına çevirmək üçün istifadə edirik.

Aşağıdakı sorğuda daha ətraflı başa düşəcəksiniz.

SELECT FROM_TZ( CAST( TO_DATE(2015-11-20 11:40:00', 'RRRR-MM-DD HH:MI:SS') AS TIMESTAMP ), 'America/Los_Angeles') AT LOCAL "Local Time" FROM DUAL;

Local Time

—————————————–

20-NOV-15 02.00.00.000000000 PM AMERICA/NEW_YORK

Beləliklə single-row funksiyalar mövzusunu bitirmiş olduq, ümid edirəm sizlərə faydalı olar 🙂