Sqlserver
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Sqlserver

Chuyển đổi ngày giờ từ múi giờ sang múi giờ trong máy chủ sql

Dấu thời gian Unix là số giây nguyên kể từ ngày 1 tháng 1 năm 1970 theo giờ UTC.

Giả sử ý bạn là bạn có một cột số nguyên trong cơ sở dữ liệu của mình với số này, thì múi giờ của máy chủ cơ sở dữ liệu của bạn không liên quan.

Đầu tiên chuyển đổi dấu thời gian thành datetime loại:

SELECT DATEADD(second, yourTimeStamp, '1970-01-01')

Đây sẽ là UTC datetime tương ứng với dấu thời gian của bạn.

Sau đó, bạn cần biết cách điều chỉnh giá trị này theo múi giờ mục tiêu của mình. Ở hầu hết các quốc gia trên thế giới, một khu vực duy nhất có thể có nhiều hiệu số, do Giờ tiết kiệm ánh sáng ban ngày.

Thật không may, SQL Server không có khả năng làm việc trực tiếp múi giờ làm việc. Vì vậy, nếu bạn đang sử dụng giờ Thái Bình Dương của Hoa Kỳ, chẳng hạn, bạn sẽ không có cách nào để biết liệu bạn nên trừ đi 7 giờ hay 8 giờ. Các cơ sở dữ liệu khác (Oracle, Postgres, MySql, v.v.) có các cách tích hợp để xử lý điều này, nhưng than ôi, SQL Server thì không. Vì vậy, nếu bạn đang tìm kiếm một giải pháp cho mục đích chung, bạn sẽ cần thực hiện một trong những điều sau:

  • Nhập dữ liệu múi giờ vào một bảng và duy trì bảng đó khi các quy tắc về múi giờ thay đổi. Sử dụng bảng đó với một loạt logic tùy chỉnh để giải quyết sự chênh lệch cho một ngày cụ thể.

  • Sử dụng xp_regread để truy cập các khóa đăng ký Windows có chứa dữ liệu múi giờ và một lần nữa sử dụng một loạt logic tùy chỉnh để giải quyết phần bù cho một ngày cụ thể. Tất nhiên, xp_regread là một điều tồi tệ để làm, yêu cầu một số quyền nhất định được cấp và không được hỗ trợ hoặc tài liệu.

  • Viết hàm SQLCLR sử dụng TimeZoneInfo lớp trong .Net. Rất tiếc, này yêu cầu lắp ráp SQLCLR "không an toàn" và có thể khiến những điều tồi tệ xảy ra.

IMHO, không có phương pháp nào trong số này là rất tốt và không có giải pháp nào tốt để thực hiện điều này trực tiếp trong SQL. Giải pháp tốt nhất sẽ là trả về giá trị UTC (số nguyên ban đầu hoặc datetime tại UTC) sang mã ứng dụng gọi điện của bạn và thực hiện chuyển đổi múi giờ ở đó (ví dụ:với TimeZoneInfo trong .Net hoặc các cơ chế tương tự trong các nền tảng khác).

TUY NHIÊN - bạn đã may mắn khi Kuwait (và luôn luôn) nằm trong khu vực không thay đổi đối với Giờ tiết kiệm ánh sáng ban ngày. Nó luôn là UTC + 03:00. Vì vậy, bạn có thể chỉ cần thêm ba giờ và trả về kết quả:

SELECT DATEADD(hour, 3, DATEADD(second, yourTimeStamp, '1970-01-01'))

Nhưng hãy lưu ý rằng đây không phải là một giải pháp có mục đích chung sẽ hoạt động ở bất kỳ múi giờ nào.

Nếu muốn, bạn có thể trả về một trong các kiểu dữ liệu SQL khác, chẳng hạn như datetimeoffset , nhưng điều này sẽ chỉ giúp bạn phản ánh rằng giá trị này bù lại ba giờ cho bất kỳ ai có thể nhìn vào nó. Nó sẽ không làm cho quá trình chuyển đổi khác đi hoặc tốt hơn.

Câu trả lời được cập nhật

Tôi đã tạo một dự án để hỗ trợ múi giờ trong SQL Server. Bạn có thể cài đặt nó từ đây . Sau đó, bạn có thể chỉ cần chuyển đổi như vậy:

SELECT Tzdb.UtcToLocal('2015-07-01 00:00:00', 'Asia/Kuwait')

Bạn có thể sử dụng bất kỳ múi giờ nào từ cơ sở dữ liệu IANA tz , bao gồm cả những nơi sử dụng thời gian tiết kiệm ánh sáng ban ngày.

Bạn vẫn có thể sử dụng phương pháp tôi đã trình bày ở trên để chuyển đổi từ dấu thời gian unix. Đặt cả hai lại với nhau:

SELECT Tzdb.UtcToLocal(DATEADD(second, yourTimeStamp, '1970-01-01'), 'Asia/Kuwait')

Đã cập nhật lại

Với SQL Server 2016, hiện đã có hỗ trợ tích hợp cho múi giờ với AT TIME ZONE bản tường trình. Điều này cũng có sẵn trong Cơ sở dữ liệu Azure SQL (v12).

SELECT DATEADD(second, yourTimeStamp, '1970-01-01') AT TIME ZONE 'Arab Standard Time'

Các ví dụ khác trong thông báo này.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. SQL 2005 CTE so với bảng TEMP Hiệu suất khi được sử dụng trong kết hợp của các bảng khác

  2. Kích hoạt không đồng bộ trong SQL Server 2005/2008

  3. Thay thế giá trị hàng bằng chuỗi trống nếu trùng lặp

  4. Làm cách nào để tính tổng số đang chạy trong SQL mà không sử dụng con trỏ?

  5. Quyền của Máy chủ SQL trên Procs được Lưu trữ với SQL động