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

Convertir 'datetimeoffset' en 'time' dans SQL Server (exemples T-SQL)

Si vous avez un datetimeoffset valeur, mais vous n'avez pas besoin de la partie de décalage de date et de fuseau horaire, en la convertissant en heure vous fera économiser beaucoup d'espace de stockage (tout en supprimant les détails inutiles de la valeur). Cet article contient des exemples de conversion d'un datetimeoffset valeur à un temps valeur dans SQL Server.

Le datetimeoffset Le type de données inclut la date et l'heure avec un décalage de fuseau horaire. Il a également une fraction de seconde comprise entre 0 et 7 (cela dépend du nombre de fractions de seconde qui lui sont attribuées). Ceci est fait en utilisant le datetimeoffset(n) syntaxe. Si vous ne le spécifiez pas, il utilisera 7 (valeur par défaut). La taille de stockage de ce type de données est de 8, 9 ou 10 octets, selon la précision utilisée. Sa précision est de 100 nanosecondes.

Le temps type de données, d'autre part, n'inclut que l'heure. Il n'inclut pas la date et il n'inclut pas le décalage de fuseau horaire. Cependant, similaire à datetimeoffset il vous permet également de spécifier une fraction de seconde comprise entre 0 et 7 (en utilisant le time(n) syntaxe). Il utilise soit 3, 4 ou 5 octets, selon sa précision.

Lorsque vous convertissez un datetimeoffset valeur à un temps type de données, vous perdez la partie date. Vous perdez également le décalage horaire. Cependant, vous réduisez également la taille de stockage de 8 à 10 octets à 3, 4 ou 5 octets. Cependant, vous n'effectuerez cette conversion que si vous n'avez pas besoin de la partie date ou du décalage horaire.

Notez que les quantités de stockage répertoriées ici sont les quantités répertoriées dans la documentation Microsoft. Cependant, ces types de données utilisent également 1 octet pour stocker la précision. Par conséquent, vous devrez ajouter 1 octet aux montants indiqués ici.

Exemple 1 – Conversion implicite

Voici un exemple de conversion implicite entre datetimeoffset et temps .

DECLARE 
  @thedatetimeoffset datetimeoffset, 
  @thetime time;
SET @thedatetimeoffset = '2025-05-21 10:15:30.1234567 +10:30';
SET @thetime = @thedatetimeoffset;
SELECT 
  @thedatetimeoffset AS 'datetimeoffset',
  @thetime AS 'time';

Résultat :

+------------------------------------+------------------+
| datetimeoffset                     | time             |
|------------------------------------+------------------|
| 2025-05-21 10:15:30.1234567 +10:30 | 10:15:30.1234567 |
+------------------------------------+------------------+

Il s'agit d'une conversion implicite car nous n'utilisons pas de fonction de conversion (comme celles ci-dessous) pour la convertir explicitement. Dans ce cas, SQL Server effectue une conversion implicite dans les coulisses lorsque nous essayons d'attribuer le datetimeoffset valeur à un temps variables.

Ici, nous pouvons voir que le temps La valeur inclut uniquement l'heure (sans le composant de date). Les composants de décalage de date et de fuseau horaire ont été supprimés de la valeur.

Dans cet exemple, les deux types de données utilisent la précision par défaut (qui se traduit par 7 décimales). Cela se traduit par le datetimeoffset valeur utilisant 10 octets et l'heure valeur en utilisant 5 octets.

Exemple 2 – Précision

Le résultat exact dépendra des paramètres de précision pour chaque type de données. Dans l'exemple suivant, le temps value utilise une précision inférieure au datetimeoffset d'origine valeur :

DECLARE 
  @thedatetimeoffset datetimeoffset(7), 
  @thetime time(3);
SET @thedatetimeoffset = '2025-05-21 10:15:30.1234567 +10:30';
SET @thetime = @thedatetimeoffset;
SELECT 
  @thedatetimeoffset AS 'datetimeoffset',
  @thetime AS 'time';

Résultat :

+------------------------------------+------------------+
| datetimeoffset                     | time             |
|------------------------------------+------------------|
| 2025-05-21 10:15:30.1234567 +10:30 | 10:15:30.1230000 |
+------------------------------------+------------------+

Mon système affiche des zéros à la fin, mais le fait est que l'heure la valeur a maintenant une précision de seulement 3 décimales par rapport aux 7 décimales utilisées par la valeur d'origine.

Réduire la précision peut également entraîner le temps valeur étant arrondie. Voici un exemple :

DECLARE 
  @thedatetimeoffset datetimeoffset(7), 
  @thetime time(3);
SET @thedatetimeoffset = '2025-05-21 10:15:30.1235555 +10:30';
SET @thetime = @thedatetimeoffset;
SELECT 
  @thedatetimeoffset AS 'datetimeoffset',
  @thetime AS 'time';

Résultat :

+------------------------------------+------------------+
| datetimeoffset                     | time             |
|------------------------------------+------------------|
| 2025-05-21 10:15:30.1234567 +10:30 | 10:15:30.1240000 |
+------------------------------------+------------------+

Dans ce cas, nous nous retrouvons avec une partie fractionnaire de 124 au lieu de 123 , car le chiffre suivant était 5 ou plus.

Exemple 3 - Conversion explicite à l'aide de CAST()

Voici un exemple de conversion explicite. Dans ce cas, j'utilise le CAST() fonction directement dans le SELECT déclaration pour convertir explicitement entre datetimeoffset et temps .

DECLARE @thedatetimeoffset datetimeoffset;
SET @thedatetimeoffset = '2025-05-21 10:15:30.1234567 +10:30';
SELECT 
  @thedatetimeoffset AS 'datetimeoffset',
  CAST(@thedatetimeoffset AS time) AS 'time'; 

Résultat :

+------------------------------------+------------------+
| datetimeoffset                     | date             |
|------------------------------------+------------------|
| 2025-05-21 10:15:30.1234567 +10:30 | 10:15:30.1234567 |
+------------------------------------+------------------+

Exemple 4 - Conversion explicite à l'aide de CONVERT()

Voici un exemple de conversion explicite utilisant le CONVERT() fonction au lieu de CAST() .

DECLARE @thedatetimeoffset datetimeoffset;
SET @thedatetimeoffset = '2025-05-21 10:15:30.1234567 +10:30';
SELECT 
  @thedatetimeoffset AS 'datetimeoffset',
  CONVERT(time, @thedatetimeoffset) AS 'time'; 

Résultat :

+------------------------------------+------------------+
| datetimeoffset                     | date             |
|------------------------------------+------------------|
| 2025-05-21 10:15:30.1234567 +10:30 | 10:15:30.1234567 |
+------------------------------------+------------------+