Sqlserver
 sql >> база данни >  >> RDS >> Sqlserver

Как да върнете Unix Timestamp в SQL Server (T-SQL)

Може да сте забелязали, че SQL Server няма еквивалент на UNIX_TIMESTAMP() на MySQL функция.

Въпреки това, не е толкова трудно да върнете времевата марка на Unix в SQL Server.

Unix timestamp (известен също като Unix Epoch time, Unix time или POSIX time) е просто броят на секундите, които са изминали от 00:00:00 четвъртък, 1 януари 1970 г., координирано универсално време (UTC). Следователно в SQL Server можем да използваме няколко T-SQL функции, за да върнем това.

SQL Server Unix Timestamp

Ето как можете да върнете времевата марка на Unix в SQL Server.

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

Резултат:

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

Така че можем да използваме DATEDIFF() функция за връщане на разликата в секунди между 1970-01-01 и сега. Използваме GETUTCDATE() функция за връщане на текущата дата и час в UTC време.

Този код ще работи до 2038 г. („2038-01-19 03:14:07“ за да бъдем точни). За времеви марки на Unix след това ще трябва леко да промените кода. Ако имате нужда от времеви печат на Unix след тази дата, прочетете нататък.

Еквивалент на MySQL Unix Timestamp

За сравнение, ако стартирам UNIX_TIMESTAMP() на MySQL точно по същото време получавам това:

SELECT UNIX_TIMESTAMP() AS 'MySQL Result';

Резултат:

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

Същият резултат. MySQL връща резултата като цяло число без знак. Ако обаче (незадължителният) аргументът за дата бъде предаден, той поддържа същия диапазон като TIMESTAMP тип данни.

Връщане на милисекунди

Ако трябва да върнете времеви печат на Unix с по-висока точност, да речем, броя на милисекунди от „1970-01-01 00:00:00.000“ UTC, ще трябва да смените DATEDIFF() функция за DATEDIFF_BIG() .

Това е така, защото DATEDIFF() връща int , което е твърде малко, за да се справи с броя милисекунди от 1970 г. насам. DATEDIFF_BIG() функция от друга страна, връща подписан bigint , което е повече от достатъчно за обработка на милисекунди.

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

Резултат:

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

Върнете наносекундите

Ето още един пример, този път стигащ чак до наносекунди от „1970-01-01 00:00:00.0000000“ UTC.

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

Резултат:

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

Проблемът от 2038 г.

Връщането на милисекунди, микросекунди и наносекунди е добре и добре, но строго погледнато, не е истинско време за Unix Epoch. Времето за Unix Epoch е броят секунди от 1970-01-01 00:00:00.

Въпреки това, DATEDIFF_BIG() все още може да бъде полезен при връщане на строго Unix Epoch време. По-специално, това може да помогне на вашата база данни да преодолее проблема от 2038 г. В този случай всичко след „2038-01-19 03:14:07“ ще трябва да бъде върнато като bigint (цяло число от 8 байта). Това е така, защото броят на секундите ще е твърде голям за int тип данни (4 байтово цяло число). Винт тип данни стига само до 2 147 483 647, докато голям достига до 9,223,372,036,854,775,807.

Следователно, за да върнете времеви марки на Unix след „2038-01-19 03:14:07“, използвайте DATEDIFF_BIG() функция вместо DATEDIFF() .

За да демонстрирате това, ето пример за използване на DATEDIFF() за да върнете Unix време точно на тази дата/час:

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

Резултат:

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

Дотук добре. Този резултат е в рамките на int диапазон от -2 147 483 648 до 2 147 483 647 (въпреки че е точно на горната граница), така че се връща правилният резултат.

Но ето какво се случва, ако го увеличим с една секунда:

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

Резултат:

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.

Получаваме грешката, защото върнатата стойност би била извън int диапазон.

Както споменахме, всичко, което трябва да направим, е да разменим DATEDIFF() за DATEDIFF_BIG() :

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

Резултат:

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

Това обаче няма да реши непременно проблемите през 2038 г., тъй като повечето потенциални проблеми вероятно ще бъдат извлечени от операционната система.

Трябва също да отбележа, че нито един от този код не е непременно имунизиран срещу „проблема от 10 000 година“, тъй като включва datetime2 тип данни, който има горен диапазон от „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. Възможни ли са GUID сблъсъци?

  2. Как бихте внедрили последователности в Microsoft SQL Server?

  3. Как да разположите приложение с база данни на sql сървър на клиенти

  4. Грешки в SQL Server при импортиране на CSV файл, въпреки че varchar(MAX) се използва за всяка колона

  5. 3 начина за връщане на редове, които съдържат буквено-цифрови знаци в SQL Server