web-dev-qa-db-fra.com

Comment puis-je convertir un Sql Server 2008 DateTimeOffset en un DateTime

J'espère convertir une table qui a un champ DATETIMEOFFSET, en un champ DATETIME MAIS recalcule l'heure en tenant compte du décalage. Ceci, en effet, convertit la valeur en UTC.

par exemple.

CreatedOn: 2008-12-19 17:30:09.0000000 +11:00

qui sera converti en

CreatedOn: 2008-12-19 06:30:09.0000000

ou

CreatedOn: 2008-12-19 06:30:09.0000000 + 00:00 -- that's a `DATETIMEOFFSET`, but `UTC`.

À votre santé :)

39
Pure.Krome

La conversion à l'aide de presque tous les styles entraîne la conversion de la valeur datetime2 en UTC.
De plus, la conversion de datetime2 à datetimeoffset définit simplement le décalage à +00:00, comme ci-dessous, c'est donc un moyen rapide de convertir de Datetimeoffset(offset!=0) à Datetimeoffset(+00:00)

declare @createdon datetimeoffset
set @createdon = '2008-12-19 17:30:09.1234567 +11:00'

select CONVERT(datetime2, @createdon, 1)
--Output: 2008-12-19 06:30:09.12

select convert(datetimeoffset,CONVERT(datetime2, @createdon, 1))
--Output: 2008-12-19 06:30:09.1234567 +00:00
55
RichardTheKiwi

J'utiliserais l'option SQL intégrée:

select SWITCHOFFSET(cast('2008-12-19 17:30:09.0000000 +11:00' as datetimeoffset),'+00:00')
26
Vipeout

Je sais que c'est une vieille question mais, si vous voulez convertir DateTimeOffset en DateTime, je pense que vous devez prendre en compte le fuseau horaire du serveur sur lequel vous effectuez la conversion. Si vous faites juste une CONVERT (datetime, @MyDate, 1), vous perdrez simplement le fuseau horaire, ce qui entraînera probablement une conversion incorrecte.

Je pense que vous devez d'abord changer le décalage de la valeur DateTimeOffset, puis faire la conversion.

DECLARE @MyDate DATETIMEOFFSET = '2013-11-21 00:00:00.0000000 -00:00';
SELECT CONVERT(DATETIME, SWITCHOFFSET(@MyDate, DATEPART(tz,SYSDATETIMEOFFSET())));

Le résultat de la conversion du '2013-11-21 00: 00: 00.0000000 -00: 00' en un DateTime sur un serveur dont le décalage est -7: 00 sera 2013-11-20 17: 00: 00.000. Avec la logique ci-dessus, il ne correspond pas au fuseau horaire du serveur ou au décalage de la valeur DateTime, il sera converti en DateTime dans le fuseau horaire des serveurs.

Je crois que vous devez le faire car une valeur DateTime inclut une hypothèse selon laquelle la valeur est dans le fuseau horaire du serveur.

19
Jeremy

Remarque: Les informations de fuseau horaire sont supprimées en conversion si aucun style ("126" ici) n'est spécifié. Il peut également être ignoré dans certains des autres styles, je ne sais pas - en tout cas, les éléments suivants s'ajustent correctement pour les informations TZ. Voir CAST et CONVERT .

select convert(datetime, cast('2008-12-19 17:30:09.0000000 +11:00' as datetimeoffset), 126) as utc;

Bonne SQL'ing.

Modifier

Je ne sais pas si cela importe, mais ... datetime Impossible de stocker ce niveau de précision/exactitude. Si ce qui précède est exécuté, les secondes fractionnaires seront tronquées à 3 chiffres (et la précision est inférieure à cela). La même chose avec datetime2 (Et datetimeoffset(7)) produit une valeur non tronquée:

select convert(datetime2, cast('2008-12-19 17:30:09.1234567 +11:00' as datetimeoffset(7)), 126) as utc;
6
user166390

Afin de tenir compte de l'heure d'été, j'ai utilisé ce qui suit:

CONVERT(
  DateTime, 
  SWITCHOFFSET(
    CONVERT(
      DateTimeOffset, 
      CONVERT(
        DateTime, 
        [time_stamp_end_of_interval], 
        120
      )
    ),
    DATENAME(
      TzOffset, 
      CONVERT(
        DateTime, 
        [time_stamp_end_of_interval], 
        120
      ) AT TIME ZONE 'Pacific Standard Time'
    )
  )
)
AS GOOD_PST

Remarque: time_stamp_end_of_interval est un varchar

0
Duane Pfeiffer