sql >> Database teknologi >  >> RDS >> Sqlserver

Konverter en dato til en anden tidszone i SQL Server

AT TIME ZONE klausul blev introduceret i SQL Server 2016 for at konvertere en dato til en datotidsforskydning værdi i en måltidszone.

Denne funktion ligner nogle andre T-SQL-funktioner, såsom SWITCHOFFSET() og TODATETIMEOFFSET() , dog AT TIME ZONE klausulen tillader/(kræver) at du angiver tidszoneforskydningen ved navn i stedet for en faktisk offsetværdi.

Denne artikel udforsker hvordan AT TIME ZONE virker og forklarer dens fordele sammenlignet med de andre nævnte funktioner.

Eksempel på brug

Her er et grundlæggende eksempel på, hvordan AT TIME ZONE klausul virker.

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]; 

Resultat (ved hjælp af lodret output):

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

Du undrer dig måske over, hvorfor Microsoft overhovedet introducerede denne funktion, når du kunne have brugt SWITCHOFFSET() funktion til at gøre det samme?

Nå, du kan ikke gør faktisk nøjagtig det samme med SWITCHOFFSET() .

Med SWITCHOFFSET() , skal du angive den faktiske tidszoneforskydning enten i formatet [+|-]TZH:TZM eller som et signeret heltal (i minutter). Det betyder, at du skal kende den nøjagtige tidszoneforskydning, og om den pågældende tidszone i øjeblikket observerer sommertid eller ej.

Med AT TIME ZONE klausul, det behøver du ikke at vide. Alt du behøver at vide er navnet på tidszonen (og her er, hvordan du får tidszonens navn).

Eksempel på sommertid

Her er et eksempel, der viser fordelen ved at bruge AT TIME ZONE med hensyn til sommertid.

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]; 

Resultat (ved hjælp af lodret output):

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

I New Zealand slutter sommertid den 5. marts 2020. Derfor bruger jeg i dette eksempel to datoer (1. marts og 7. marts).

Når jeg konverterer dem til 'New Zealand Standard Time', AT TIME ZONE inkluderer automatisk sommertid i sin beregning og returnerer den gældende dato/tid.

Så vi kan se, at datoen 1. marts bruger en tidszoneforskydning på +13:00, og datoen 7. marts bruger +12:00 (fordi sommertid sluttede den 5. marts).

Hvis jeg havde brugt SWITCHOFFSET() Jeg skulle have vidst, hvilken tidszoneforskydning jeg skulle bruge for hver dato.

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]; 

Resultat (ved hjælp af lodret output):

@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

Konvertering fra datoer uden tidszoneforskydning

Du kan også bruge AT TIME ZONE på datoer uden tidszoneforskydning. Faktisk accepterer funktionen ethvert udtryk, der kan opløses til en smalldatetime , datotid , datetime2 eller datotidsforskydning værdi.

Når du gør dette, skal du dog være opmærksom på, hvordan resultatet udregnes. Når datoen er angivet uden forskydningsoplysninger, anvender funktionen forskydningen af ​​tidszonen, forudsat at inputdatoen er i måltidszonen.

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]; 

Resultat:

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

Bemærk, at selvom tidszoneforskydningerne blev anvendt som specificeret, påvirkede dette ikke datoen/klokkeslættet. Begge resulterende dato/klokkeslæt har samme værdi – kun tidszoneforskydningen er ændret.

Hvis dette ikke er, hvad du ønsker, så kan du tilføje AT TIME ZONE 'UTC' til blandingen for først at konvertere de originale datoer til UTC, før de konverteres til den ønskede tidszone.

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]; 

Resultat:

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

  1. MariaDB JSON_LENGTH() Forklaret

  2. Er der en Profiler-ækvivalent til MySql?

  3. Beregn decil i MySQL baseret på totaler

  4. Sådan begrænser du resultater i MySQL, PostgreSQL og SQLite