Sqlserver
 sql >> Base de données >  >> RDS >> Sqlserver

Comment renvoyer l'horodatage Unix dans SQL Server (T-SQL)

Vous avez peut-être remarqué que SQL Server n'a pas d'équivalent de UNIX_TIMESTAMP() de MySQL fonction.

Cependant, il n'est pas si difficile de renvoyer l'horodatage Unix dans SQL Server.

L'horodatage Unix (également appelé heure d'époque Unix, heure Unix ou heure POSIX) est simplement le nombre de secondes qui se sont écoulées depuis 00:00:00 jeudi 1er janvier 1970, temps universel coordonné (UTC). Par conséquent, dans SQL Server, nous pouvons utiliser quelques fonctions T-SQL pour renvoyer ceci.

Horodatage SQL Server Unix

Voici comment vous pouvez renvoyer l'horodatage Unix dans SQL Server.

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

Résultat :

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

Nous pouvons donc utiliser le DATEDIFF() fonction pour renvoyer la différence en secondes entre 1970-01-01 et maintenant. Nous utilisons le GETUTCDATE() fonction pour renvoyer la date et l'heure actuelles en heure UTC.

Ce code fonctionnera jusqu'en 2038 ("2038-01-19 03:14:07" pour être précis). Pour les horodatages Unix après cela, vous devrez modifier légèrement le code. Si vous avez besoin d'un horodatage Unix après cette date, lisez la suite.

Équivalent de l'horodatage MySQL Unix

Pour une comparaison, si j'exécute le UNIX_TIMESTAMP() de MySQL exactement au même moment, j'obtiens ceci :

SELECT UNIX_TIMESTAMP() AS 'MySQL Result';

Résultat :

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

Même résultat. MySQL renvoie le résultat sous la forme d'un entier non signé. Cependant, si l'argument date (facultatif) est passé, il prend en charge la même plage que le TIMESTAMP type de données.

Renvoyer les millisecondes

Si vous devez renvoyer un horodatage Unix avec une plus grande précision, par exemple, le nombre de millisecondes depuis '1970-01-01 00:00:00.000' UTC, vous devrez échanger le DATEDIFF() fonction pour DATEDIFF_BIG() .

C'est parce que DATEDIFF() renvoie un int , qui est trop petit pour gérer le nombre de millisecondes depuis 1970. Le DATEDIFF_BIG() d'autre part, renvoie un bigint signé , ce qui est plus que suffisant pour gérer les millisecondes.

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

Résultat :

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

Renvoyer les nanosecondes

Voici un autre exemple, cette fois allant jusqu'aux nanosecondes depuis 1970-01-01 00:00:00.0000000 UTC.

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

Résultat :

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

Le problème de l'an 2038

Renvoyer des millisecondes, des microsecondes et des nanosecondes est très bien, mais à proprement parler, ce n'est pas le vrai temps Unix Epoch. Le temps Unix Epoch est le nombre de secondes depuis '1970-01-01 00:00:00'.

Cependant, le DATEDIFF_BIG() peut toujours être utile lors du retour de l'heure Unix Epoch stricte. En particulier, cela pourrait aider votre base de données à surmonter le problème 2038. Dans ce cas, tout ce qui suit "2038-01-19 03:14:07" devra être renvoyé en tant que bigint (un entier de 8 octets). C'est parce que le nombre de secondes sera trop grand pour un int type de données (un entier de 4 octets). Le int le type de données ne va que jusqu'à 2 147 483 647, alors qu'un bigint monte à 9 223 372 036 854 775 807.

Par conséquent, pour renvoyer les horodatages Unix au-delà de '2038-01-19 03:14:07', utilisez le DATEDIFF_BIG() fonction au lieu de DATEDIFF() .

Pour le démontrer, voici un exemple d'utilisation de DATEDIFF() pour renvoyer l'heure Unix exactement à cette date/heure :

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

Résultat :

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

Jusqu'ici tout va bien. Ce résultat est dans le int plage de -2 147 483 648 à 2 147 483 647 (bien que ce soit juste à la limite supérieure) afin que le résultat correct soit renvoyé.

Mais voici ce qui se passe si nous l'augmentons d'une seconde :

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

Résultat :

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.

Nous obtenons l'erreur car la valeur renvoyée serait en dehors de l'int plage.

Donc, comme mentionné, tout ce que nous avons à faire est d'échanger DATEDIFF() pour DATEDIFF_BIG() :

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

Résultat :

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

Cependant, cela ne résoudra pas nécessairement tous les problèmes de l'année 2038, car la plupart des problèmes potentiels proviendraient probablement du système d'exploitation.

Je dois également souligner qu'aucun de ces codes ne sera nécessairement à l'abri du "problème de l'année 10 000", car il implique le datetime2 type de données, dont la plage supérieure est "9999-12-31".