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

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

Cet article contient des exemples de conversion d'un datetime valeur à un datetimeoffset valeur dans SQL Server.

Lorsque vous convertissez un datetime valeur à datetimeoffset , la valeur résultante dépendra de la précision en fractions de seconde que vous attribuez à datetimeoffset , ainsi que tout décalage de fuseau horaire que vous spécifiez.

La dateheure Le type de données a un maximum de 3 chiffres pour sa fraction de seconde. Sa précision est arrondie à des incréments de .000, .003 ou .007 secondes.

Le datetimeoffset Le type de données, d'autre part, vous permet de spécifier une précision fractionnaire de secondes de 0 à 7. Si vous ne le spécifiez pas, il utilisera 7 (la valeur par défaut). Il a également un décalage de fuseau horaire et peut conserver tous les décalages dans la valeur d'origine. Cependant, datetime n'a pas de prise en compte du fuseau horaire, il n'y a donc pas de valeurs existantes à conserver. Dans ce cas, le décalage horaire par défaut est +00:00.

SQL Server a en fait le TODATETIMEOFFSET() fonction, qui est spécifiquement conçue pour convertir une valeur de date/heure en datetimeoffset et ajoutez un décalage de fuseau horaire. Cependant, il y a un détail subtil à prendre en compte lors de l'utilisation de cette fonction, et je l'explique ci-dessous (avec des exemples).

Exemple 1 – Conversion implicite

Tout d'abord, voici un exemple de conversion implicite entre datetime et datetimeoffset .

DECLARE 
  @thedatetime datetime, 
  @thedatetimeoffset datetimeoffset(7);
SET @thedatetime = '2025-05-21 10:15:30.123';
SET @thedatetimeoffset = @thedatetime;
SELECT 
  @thedatetime AS 'datetime',
  @thedatetimeoffset AS 'datetimeoffset(7)';

Résultat :

+-------------------------+------------------------------------+
| datetime                | datetimeoffset(7)                  |
|-------------------------+------------------------------------|
| 2025-05-21 10:15:30.123 | 2025-05-21 10:15:30.1233333 +00:00 |
+-------------------------+------------------------------------+

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 datetime valeur à un datetimeoffset variables.

Nous pouvons voir que le datetimeoffset la variable a plus de précision en fractions de secondes, et nous nous retrouvons avec une partie fractionnaire de 1233333 (contre 123 pour le datetime valeur). Nous nous retrouvons également avec un décalage de fuseau horaire de +00:00 .

L'utilisation d'une précision de 7 fractions de seconde provoque datetimeoffset utiliser 10 octets pour le stockage (11 octets si vous incluez l'octet qui stocke sa précision). À titre de comparaison, datetime utilise seulement 8 octets. Cependant, vous pouvez réduire la précision de datetimeoffset valeur en remplaçant le 7 par un chiffre inférieur. C'est le même concept que lors de l'utilisation de datetime2 Type de données. Voir Convertir 'datetime' en 'datetime2' dans SQL Server pour des exemples de la façon dont cela peut affecter le résultat final.

Exemple 2 – Arrondi

La dateheure Le type de données est arrondi à des incréments de 0,000, 0,003 ou 0,007 seconde. Même si vous le définissez explicitement sur une autre valeur, il sera arrondi. Cela pourrait vous causer beaucoup de confusion si vous ne savez pas comment cela fonctionne. Non seulement cela peut prêter à confusion lors de l'utilisation de datetime en soi, cela peut entraîner une confusion supplémentaire lors de la conversion de cette valeur en un autre type de données.

Voici un exemple qui illustre ce que je veux dire.

DECLARE 
  @thedatetime datetime, 
  @thedatetimeoffset datetimeoffset;
SET @thedatetime = '2025-05-21 10:15:30.125';
SET @thedatetimeoffset = @thedatetime;
SELECT 
  @thedatetime AS 'datetime',
  @thedatetimeoffset AS 'datetimeoffset(7)';

Résultat :

+-------------------------+------------------------------------+
| datetime                | datetimeoffset(7)                  |
|-------------------------+------------------------------------|
| 2025-05-21 10:15:30.127 | 2025-05-21 10:15:30.1266667 +00:00 |
+-------------------------+------------------------------------+

Dans cet exemple, j'ai défini les fractions de seconde sur 125 mais datetime arrondi à 127 (car ce type de données ne peut être arrondi qu'à des incréments de .000, .003 ou .007 secondes).

Le datetimeoffset d'autre part, définissez les secondes fractionnaires sur 1266667 .

Cependant, si nous définissons simplement la valeur initiale sur datetimeoffset en premier lieu, sa partie fractionnaire aurait renvoyé 1250000 .

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 datetime et datetimeoffset .

DECLARE @thedatetime datetime;
SET @thedatetime = '2025-05-21 10:15:30.125';
SELECT 
  @thedatetime AS 'datetime',
  CAST(@thedatetime AS datetimeoffset(7)) AS 'datetimeoffset(7)';

Résultat :

+-------------------------+------------------------------------+
| datetime                | datetimeoffset(7)                  |
|-------------------------+------------------------------------|
| 2025-05-21 10:15:30.127 | 2025-05-21 10:15:30.1266667 +00:00 |
+-------------------------+------------------------------------+

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

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

DECLARE @thedatetime datetime;
SET @thedatetime = '2025-05-21 10:15:30.125';
SELECT 
  @thedatetime AS 'datetime',
  CONVERT(datetimeoffset(7), @thedatetime) AS 'datetimeoffset(7)';

Résultat :

+-------------------------+------------------------------------+
| datetime                | datetimeoffset(7)                  |
|-------------------------+------------------------------------|
| 2025-05-21 10:15:30.127 | 2025-05-21 10:15:30.1266667 +00:00 |
+-------------------------+------------------------------------+

Exemple 5 - Modification du décalage horaire

Si vous vous donnez la peine de convertir votre datetime valeurs à datetimeoffset , vous avez probablement besoin du décalage horaire. Et il y a de fortes chances que vous souhaitiez qu'il soit réglé sur autre chose que +00:00.

Heureusement, vous pouvez utiliser le TODATETIMEOFFSET() fonction pour modifier le décalage.

Vous pouvez également utiliser cette fonction pour convertir le datetime d'origine valeur à un datetimeoffset valeur. Cette fonction accepte une valeur de date/heure (qui peut se résoudre en une datetime2 valeur) et une valeur de décalage.

Voici un exemple :

DECLARE @thedatetime datetime, @thedatetimeoffset datetimeoffset;
SET @thedatetime = '2025-05-21 10:15:30.125';
SET @thedatetimeoffset = TODATETIMEOFFSET(@thedatetime, '+07:00');
SELECT 
  @thedatetime AS 'datetime',
  @thedatetimeoffset AS 'datetimeoffset';

Résultat :

+-------------------------+------------------------------------+
| datetime                | datetimeoffset(7)                  |
|-------------------------+------------------------------------|
| 2025-05-21 10:15:30.127 | 2025-05-21 10:15:30.1270000 +07:00 |
+-------------------------+------------------------------------+

Et voici un exemple utilisant la fonction dans le SELECT déclaration :

DECLARE @thedatetime datetime = '2025-05-21 10:15:30.125';
SELECT 
  @thedatetime AS 'datetime',
  TODATETIMEOFFSET(@thedatetime, '+07:00') AS 'datetimeoffset';

Résultat :

+-------------------------+------------------------------------+
| datetime                | datetimeoffset(7)                  |
|-------------------------+------------------------------------|
| 2025-05-21 10:15:30.127 | 2025-05-21 10:15:30.1270000 +07:00 |
+-------------------------+------------------------------------+

Un point important sur le TODATETIMEOFFSET() est qu'elle utilise la même précision fractionnaire que l'argument date/heure qui lui est passé. Dans ce cas, il s'agit d'un datetime argument, il a donc une échelle de 3 (c'est-à-dire 3 secondes fractionnaires). Cela peut ou non être un problème pour vous. Si c'est le cas, vous pouvez toujours le convertir en un datetimeoffset d'abord, puis passez cette valeur convertie à TODATETIMEOFFSET() .

Exemple :

DECLARE @thedatetime datetime, @thedatetimeoffset datetimeoffset(7);
SET @thedatetime = '2025-05-21 10:15:30.125';
SET @thedatetimeoffset = @thedatetime;
SELECT 
  @thedatetime AS 'datetime',
  @thedatetimeoffset AS 'datetimeoffset',
  TODATETIMEOFFSET(@thedatetimeoffset, '+07:00') AS 'Modified';

Résultat (en utilisant la sortie verticale) :

datetime       | 2025-05-21 10:15:30.127
datetimeoffset | 2025-05-21 10:15:30.1266667 +00:00
Modified       | 2025-05-21 10:15:30.1266667 +07:00