TIMESTAMP WITH LOCAL TIME ZONE
hoạt động như thế này:Khi bạn phải làm việc với múi giờ trong ứng dụng của mình thì cách tiếp cận phổ biến là
Đó chính xác là cách TIMESTAMP WITH LOCAL TIME ZONE
hoạt động - sự khác biệt duy nhất là
Vì lý do đó, bạn không thể thay đổi DBTIMEZONE
(với ALTER DATABASE SET TIME_ZONE='...';
) trên cơ sở dữ liệu của bạn nữa nếu cơ sở dữ liệu chứa một bảng có TIMESTAMP WITH LOCAL TIME ZONE
và cột chứa dữ liệu.
SYSTIMESTAMP
được kiểm tra trong múi giờ của hệ điều hành máy chủ cơ sở dữ liệu. DBTIMEZONE
không múi giờ của SYSTIMESTAMP
hoặc SYSDATE
.
DBTIMEZONE
xác định định dạng bộ nhớ trong của TIMESTAMP WITH LOCAL TIME ZONE
các cột kiểu dữ liệu. Quên điều này đi, tôi không thể tưởng tượng bất kỳ trường hợp sử dụng nào mà bạn sẽ cần đến nó.
Trên thực tế, bảng của bạn tương đương với lựa chọn này:
select
CAST(systimestamp AS timestamp(0) with local time zone) as SYSTIMESTAMP_COL,
CAST(sysdate AS timestamp(0) with local time zone) as SYSDATE_COL,
CAST(current_timestamp AS timestamp(0) with local time zone) as CURRENT_TIMESTAMP_COL,
CAST(timestamp '2017-03-15 19:02:00' AS timestamp(0) with local time zone) as DATE_COL
from dual;
Khi bạn thực hiện CAST({time without time zone} with local time zone)
thì bạn cố gắng chuyển đổi giá trị ngày / giờ mà không có bất kỳ thông tin múi giờ nào thành giá trị ngày / giờ có múi giờ. Về nguyên tắc, điều này là không thể thực hiện được vì Oracle thiếu thông tin múi giờ, do đó Oracle giả định là một múi giờ. Nếu bạn thực hiện truyền như vậy thì Oracle luôn coi {thời gian không có múi giờ} như đã cho trong SESSIONTIMEZONE
(trong thời điểm chuyển đổi).
Vì vậy, CAST(sysdate AS timestamp(0) with local time zone)
tương đương với
CAST(FROM_TZ(TO_TIMESTAMP(SYSDATE), SESSIONTIMEZONE) AS TIMESTAMP(0) WITH LOCAL TIME ZONE)`
tương ứng CAST(timestamp '2017-03-15 19:02:00' AS timestamp(0) with local time zone)
nghĩa là
CAST(FROM_TZ(TIMESTAMP '2017-03-15 19:02:00', SESSIONTIMEZONE) AS TIMESTAMP(0) WITH LOCAL TIME ZONE)
Đối với SYSDATE
điều này thực sự sai, vì SYSDATE
được cung cấp trong múi giờ của hệ điều hành máy chủ cơ sở dữ liệu không phải trong SESSIONTIMEZONE. Đối với cái thứ hai, nó phụ thuộc vào ý định của bạn cho dù kết quả có chính xác hay không.
SYSTIMESTAMP
trả về giá trị TIMESTAMP WITH TIME ZONE
, nó luôn độc lập với SESSIONTIMEZONE
hiện tại của bạn . Nhưng nếu bạn chuyển đổi thành TIMESTAMP WITH LOCAL TIME ZONE
tất nhiên nó sẽ được chuyển đổi thành múi giờ địa phương hiện tại của bạn. Bạn cũng có thể sử dụng CURRENT_TIMESTAMP
hoặc SYSTIMESTAMP AT LOCAL
điều này ít nhiều giống nhau.
Mã này
có vẻ là sai. Kết quả phải là
-- SYSTIMESTAMP_COL 15/03/2017 16:01:14
-- SYSDATE_COL 15/03/2017 19:01:14
-- CURRENT_TIMESTAMP_COL 15/03/2017 16:01:14
-- DATE_COL 15/03/2017 19:02:00
Sự khác biệt trông như bình thường nhưng các giá trị tuyệt đối dường như bị "giả mạo" (hoặc có vấn đề thực sự với cơ sở dữ liệu của bạn).