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

Cách trả lại dấu thời gian Unix trong SQL Server (T-SQL)

Bạn có thể nhận thấy rằng SQL Server không có UNIX_TIMESTAMP() của MySQL chức năng.

Tuy nhiên, không quá khó để trả lại dấu thời gian Unix trong SQL Server.

Dấu thời gian Unix (còn được gọi là thời gian Unix Epoch, Unix time, hoặc POSIX time) chỉ đơn giản là số giây đã trôi qua kể từ 00:00:00 Thứ Năm, ngày 1 tháng 1 năm 1970, Giờ Phối hợp Quốc tế (UTC). Do đó, trong SQL Server, chúng ta có thể sử dụng một số hàm T-SQL để trả về giá trị này.

Dấu thời gian của SQL Server Unix

Đây là cách bạn có thể trả lại dấu thời gian Unix trong SQL Server.

SELECT DATEDIFF(SECOND,'1970-01-01', GETUTCDATE()) AS 'SQL Server Result';

Kết quả:

+---------------------+
| SQL Server Result   |
|---------------------|
| 1560833178          |
+---------------------+

Vì vậy, chúng ta có thể sử dụng DATEDIFF() hàm để trả về sự khác biệt tính bằng giây giữa 1970-01-01 và bây giờ. Chúng tôi sử dụng GETUTCDATE() chức năng trả về ngày và giờ hiện tại theo giờ UTC.

Mã này sẽ hoạt động cho đến năm 2038 (chính xác là "2038-01-19 03:14:07"). Đối với dấu thời gian Unix sau đó, bạn sẽ cần sửa đổi mã một chút. Nếu bạn cần dấu thời gian Unix quá ngày đó, hãy đọc tiếp.

MySQL Unix Timestamp Tương đương

Để so sánh, nếu tôi chạy UNIX_TIMESTAMP() của MySQL đồng thời, tôi nhận được điều này:

SELECT UNIX_TIMESTAMP() AS 'MySQL Result';

Kết quả:

+--------------+
| MySQL Result |
+--------------+
|   1560833178 |
+--------------+

Cùng một kết quả. MySQL trả về kết quả là một số nguyên không dấu. Tuy nhiên, nếu đối số ngày (tùy chọn) được truyền, nó sẽ hỗ trợ cùng một phạm vi với TIMESTAMP kiểu dữ liệu.

Trả lại mili giây

Nếu bạn cần trả lại dấu thời gian Unix với độ chính xác cao hơn, chẳng hạn như số mili giây kể từ ‘1970-01-01 00:00:00.000’ UTC, bạn sẽ cần hoán đổi DATEDIFF() hàm cho DATEDIFF_BIG() .

Điều này là do DATEDIFF() trả về một int , quá nhỏ để xử lý số mili giây kể từ năm 1970. DATEDIFF_BIG() mặt khác, trả về một bigint đã ký , quá đủ để xử lý mili giây.

SELECT DATEDIFF_BIG(MILLISECOND,'1970-01-01 00:00:00.000', SYSUTCDATETIME()) Milliseconds;

Kết quả:

+----------------+
| Milliseconds   |
|----------------|
| 1560835305461  |
+----------------+

Trả lại Nano giây

Đây là một ví dụ khác, lần này tính đến từng nano giây kể từ '1970-01-01 00:00:00.0000000' UTC.

SELECT DATEDIFF_BIG(NANOSECOND,'1970-01-01 00:00:00.0000000', SYSUTCDATETIME()) Nanoseconds;

Kết quả:

+---------------------+
| Nanoseconds         |
|---------------------|
| 1560835321500279300 |
+---------------------+

Vấn đề năm 2038

Trả lại mili giây, micro giây và nano giây đều tốt và tốt, nhưng nói đúng ra, đó không phải là thời gian của Unix Epoch. Thời gian của Unix Epoch là số giây kể từ '1970-01-01 00:00:00'.

Tuy nhiên, DATEDIFF_BIG() vẫn có thể hữu ích khi trả về thời gian nghiêm ngặt của Kỷ nguyên Unix. Đặc biệt, nó có thể giúp cơ sở dữ liệu của bạn khắc phục sự cố năm 2038. Trong trường hợp này, mọi thứ sau ‘2038-01-19 03:14:07’ sẽ cần được trả lại dưới dạng bigint (một số nguyên 8 byte). Điều này là do số giây sẽ quá lớn đối với int kiểu dữ liệu (số nguyên 4 byte). int loại dữ liệu chỉ lên đến 2.147.483.647, trong khi bigint tăng lên 9.223.372.036.854.775.807.

Do đó, để trả về dấu thời gian Unix trong quá khứ ‘2038-01-19 03:14:07’, hãy sử dụng DATEDIFF_BIG() hàm thay vì DATEDIFF() .

Để chứng minh điều này, đây là một ví dụ về việc sử dụng DATEDIFF() để trả về thời gian Unix vào chính xác ngày / giờ đó:

SELECT DATEDIFF(SECOND,'1970-01-01', '2038-01-19 03:14:07') AS 'Unix Epoch time';

Kết quả:

+-------------------+
| Unix Epoch time   |
|-------------------|
| 2147483647        |
+-------------------+

Càng xa càng tốt. Kết quả này nằm trong int phạm vi từ -2,147,483,648 đến 2,147,483,647 (mặc dù nó ở ngay giới hạn trên) để trả về kết quả chính xác.

Nhưng đây là những gì sẽ xảy ra nếu chúng tôi tăng nó lên một giây:

SELECT DATEDIFF(SECOND,'1970-01-01', '2038-01-19 03:14:08') AS 'Unix Epoch time';

Kết quả:

The datediff function resulted in an overflow. The number of dateparts separating two date/time instances is too large. Try to use datediff with a less precise datepart.

Chúng tôi gặp lỗi vì giá trị trả về sẽ nằm ngoài int phạm vi.

Vì vậy, như đã đề cập, tất cả những gì chúng ta cần làm là hoán đổi DATEDIFF() cho DATEDIFF_BIG() :

SELECT DATEDIFF_BIG(SECOND,'1970-01-01', '2038-01-19 03:14:08') AS 'Unix Epoch time';

Kết quả:

+-------------------+
| Unix Epoch time   |
|-------------------|
| 2147483648        |
+-------------------+

Tuy nhiên, điều này không nhất thiết phải giải quyết được tất cả các vấn đề của năm 2038, vì hầu hết các vấn đề tiềm ẩn có thể bắt nguồn từ hệ điều hành.

Tôi cũng nên chỉ ra rằng không có mã nào trong số này sẽ không nhất thiết miễn nhiễm với “Vấn đề 10.000 năm”, vì nó liên quan đến datetime2 kiểu dữ liệu có phạm vi trên là ‘9999-12-31’.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. tsql trả về một bảng từ một hàm hoặc thủ tục lưu trữ

  2. Xóa tài khoản thư cơ sở dữ liệu (SSMS)

  3. Cách bỏ tất cả các Khóa chính khỏi tất cả các bảng trong Cơ sở dữ liệu SQL Server - Hướng dẫn SQL Server / TSQL Phần 65

  4. nvarchar (tối đa) so với NText

  5. Cập nhật SQL từ Bảng này sang Bảng khác dựa trên khớp ID