sql >> Database >  >> RDS >> Sqlserver

Converteer een datum naar een andere tijdzone in SQL Server

De AT TIME ZONE clausule is geïntroduceerd in SQL Server 2016 om een ​​datum om te zetten in een datetimeoffset waarde in een doeltijdzone.

Deze functie is vergelijkbaar met sommige andere T-SQL-functies, zoals SWITCHOFFSET() en TODATETIMEOFFSET() , echter, de AT TIME ZONE clausule staat/(vereist) u toe om de tijdzone-offset op naam te specificeren, in plaats van een werkelijke offset-waarde.

Dit artikel onderzoekt hoe AT TIME ZONE werkt, en legt de voordelen uit in vergelijking met de andere genoemde functies.

Gebruiksvoorbeeld

Hier is een eenvoudig voorbeeld van hoe de AT TIME ZONE clausule werkt.

DECLARE @dto datetimeoffset = '2020-04-01 00:00:00.0000000 +00:00';
SELECT
  @dto AS [Original],
  @dto AT TIME ZONE 'New Zealand Standard Time' AS [NZ Time];

Resultaat (met verticale uitvoer):

Original | 2020-04-01 00:00:00.0000000 +00:00
NZ Time  | 2020-04-01 13:00:00.0000000 +13:00

Je vraagt ​​je misschien af ​​waarom Microsoft deze functie überhaupt heeft geïntroduceerd terwijl je de SWITCHOFFSET() had kunnen gebruiken functie om hetzelfde te doen?

Nou, je kunt niet doe eigenlijk precies hetzelfde met SWITCHOFFSET() .

Met SWITCHOFFSET() , moet u de werkelijke tijdzone-offset opgeven in het formaat [+|-]TZH:TZM of als een geheel getal met teken (voor minuten). Dit betekent dat u de exacte tijdzone-offset moet weten, en of die tijdzone momenteel zomertijd in acht neemt.

Met de AT TIME ZONE clausule, dat hoeft u niet te weten. Het enige dat u hoeft te weten, is de naam van de tijdzone (en hier leest u hoe u de naam van de tijdzone kunt krijgen).

Zomertijdvoorbeeld

Hier is een voorbeeld dat het voordeel laat zien van het gebruik van AT TIME ZONE wat betreft de zomertijd.

DECLARE @dto1 datetimeoffset, @dto2 datetimeoffset;
SET @dto1 = '2020-04-01 00:00:00.0000000 +00:00';
SET @dto2 = '2020-04-07 00:00:00.0000000 +00:00';
SELECT
  @dto1 AS [@dto1],
  @dto2 AS [@dto2],
  @dto1 AT TIME ZONE 'New Zealand Standard Time' AS [NZ Time: @dto1],
  @dto2 AT TIME ZONE 'New Zealand Standard Time' AS [NZ Time: @dto2];

Resultaat (met verticale uitvoer):

@dto1          | 2020-04-01 00:00:00.0000000 +00:00
@dto2          | 2020-04-07 00:00:00.0000000 +00:00
NZ Time: @dto1 | 2020-04-01 13:00:00.0000000 +13:00
NZ Time: @dto2 | 2020-04-07 12:00:00.0000000 +12:00

In Nieuw-Zeeland eindigt de zomertijd op 5 maart 2020. Daarom gebruik ik in dit voorbeeld twee datums (1 maart en 7 maart).

Als ik ze converteer naar 'New Zealand Standard Time', AT TIME ZONE neemt automatisch de zomertijd op in de berekening en geeft de toepasselijke datum/tijd terug.

We kunnen dus zien dat de datum van 1 maart een tijdzoneverschuiving van +13:00 gebruikt en de datum van 7 maart +12:00 (omdat de zomertijd eindigde op 5 maart).

Als ik SWITCHOFFSET() had gebruikt Ik had moeten weten welke tijdzone ik voor elke datum moest gebruiken.

DECLARE @dto1 datetimeoffset, @dto2 datetimeoffset;
SET @dto1 = '2020-04-01 00:00:00.0000000 +00:00';
SET @dto2 = '2020-04-07 00:00:00.0000000 +00:00';
SELECT
  @dto1 AS [@dto1],
  @dto2 AS [@dto2],
  SWITCHOFFSET(@dto1, '+12:00') AS [+12:00],
  SWITCHOFFSET(@dto2, '+13:00') AS [+13:00];

Resultaat (met verticale uitvoer):

@dto1  | 2020-04-01 00:00:00.0000000 +00:00
@dto2  | 2020-04-07 00:00:00.0000000 +00:00
+12:00 | 2020-04-01 12:00:00.0000000 +12:00
+13:00 | 2020-04-07 13:00:00.0000000 +13:00

Converteren van datums zonder tijdzoneverschuiving

U kunt ook AT TIME ZONE . gebruiken op datums zonder tijdzoneverschuiving. In feite accepteert de functie elke uitdrukking die kan worden omgezet in een smalldatetime , datumtijd , datetime2 , of datetimeoffset waarde.

Wanneer u dit echter doet, moet u er rekening mee houden hoe het resultaat wordt berekend. Wanneer de datum wordt geleverd zonder offset-informatie, past de functie de offset van de tijdzone toe, ervan uitgaande dat de ingevoerde datum zich in de doeltijdzone bevindt.

DECLARE @dt1 smalldatetime, @dt2 smalldatetime;
SET @dt1 = '2020-04-01 00:00:00';
SET @dt2 = '2020-04-07 00:00:00';
SELECT
  @dt1 AS [@dt1],
  @dt2 AS [@dt2],
  @dt1 AT TIME ZONE 'New Zealand Standard Time' AS [NZ Time: @dt1],
  @dt2 AT TIME ZONE 'New Zealand Standard Time' AS [NZ Time: @dt2];

Resultaat:

@dt1          | 2020-04-01 00:00:00
@dt2          | 2020-04-07 00:00:00
NZ Time: @dt1 | 2020-04-01 00:00:00.0000000 +13:00
NZ Time: @dt2 | 2020-04-07 00:00:00.0000000 +12:00

Merk op dat hoewel de tijdzone-offsets werden toegepast zoals gespecificeerd, dit geen invloed had op de datum/tijd. Beide resulterende datums/tijden hebben dezelfde waarde - alleen de tijdzone-offset is gewijzigd.

Als dit niet is wat je wilt, dan kun je AT TIME ZONE 'UTC' . toevoegen aan de mix om eerst de originele datums naar UTC te converteren, voordat ze worden geconverteerd naar de gewenste tijdzone.

DECLARE @dt1 smalldatetime, @dt2 smalldatetime;
SET @dt1 = '2020-04-01 00:00:00';
SET @dt2 = '2020-04-07 00:00:00';
SELECT
  @dt1 AS [@dt1],
  @dt2 AS [@dt2],
  @dt1 AT TIME ZONE 'UTC' AT TIME ZONE 'New Zealand Standard Time' AS [NZ Time: @dt1],
  @dt2 AT TIME ZONE 'UTC' AT TIME ZONE 'New Zealand Standard Time' AS [NZ Time: @dt2];

Resultaat:

@dt1          | 2020-04-01 00:00:00
@dt2          | 2020-04-07 00:00:00
NZ Time: @dt1 | 2020-04-01 13:00:00.0000000 +13:00
NZ Time: @dt2 | 2020-04-07 12:00:00.0000000 +12:00

  1. Overeenkomsten en verschillen tussen RANK-, DENSE_RANK- en ROW_NUMBER-functies

  2. Postgres kon geen verbinding maken met de server

  3. Kan argument niet binden aan index 2 omdat de index buiten bereik is

  4. Android:hoe een cursor opnieuw opvragen om ListView te vernieuwen na het verwijderen van de databaserij?