sql >> Databáze >  >> RDS >> Sqlserver

Převést datum na jiné časové pásmo v SQL Server

AT TIME ZONE klauzule byla zavedena v SQL Server 2016 pro převod data na datetimeoffset hodnotu v cílovém časovém pásmu.

Tato funkce je podobná některým dalším funkcím T-SQL, jako je SWITCHOFFSET() a TODATETIMEOFFSET() , nicméně AT TIME ZONE klauzule povoluje/(vyžaduje), abyste specifikovali posun časového pásma jménem namísto skutečné hodnoty posunu.

Tento článek se zabývá tím, jak AT TIME ZONE funguje a vysvětluje jeho výhody ve srovnání s ostatními zmíněnými funkcemi.

Příklad použití

Zde je základní příklad toho, jak AT TIME ZONE doložka funguje.

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

Výsledek (při použití vertikálního výstupu):

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

Možná se divíte, proč Microsoft vůbec zavedl tuto funkci, když jste mohli použít SWITCHOFFSET() funkce dělat totéž?

No, nemůžete vlastně udělejte přesně to samé s SWITCHOFFSET() .

Pomocí SWITCHOFFSET() , musíte zadat skutečný posun časového pásma buď ve formátu [+|-]TZH:TZM nebo jako celé číslo se znaménkem (pro minuty). To znamená, že potřebujete znát přesný posun časového pásma, a zda v daném časovém pásmu aktuálně platí letní čas.

Pomocí AT TIME ZONE klauzule, to nemusíte vědět. Vše, co potřebujete znát, je název časového pásma (a zde je návod, jak název časového pásma zjistit).

Příklad letního času

Zde je příklad, který demonstruje výhody použití AT TIME ZONE s ohledem na letní čas.

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

Výsledek (při použití vertikálního výstupu):

@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

Na Novém Zélandu končí letní čas 5. března 2020. Proto v tomto příkladu používám dvě data (1. března a 7. března).

Když je převedu na ‚novozélandský standardní čas‘, AT TIME ZONE automaticky zahrne do výpočtu letní čas a vrátí platné datum/čas.

Můžeme tedy vidět, že datum 1. března používá posun časového pásma +13:00 a datum 7. března používá +12:00 (protože letní čas skončil 5. března).

Kdybych použil SWITCHOFFSET() Musel bych vědět, jaké posunutí časového pásma použít pro každé datum.

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

Výsledek (při použití vertikálního výstupu):

@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

Převod z dat bez posunu časového pásma

Můžete také použít AT TIME ZONE na data bez posunu časového pásma. Funkce ve skutečnosti přijímá jakýkoli výraz, který lze přeložit na smalldatetime , datum a čas , datetime2 nebo datetimeoffset hodnotu.

Když to však uděláte, musíte si uvědomit, jak se výsledek vypočítá. Pokud je datum poskytnuto bez informací o posunu, funkce použije posun časového pásma za předpokladu, že vstupní datum je v cílovém časovém pásmu.

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

Výsledek:

@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

Všimněte si, že ačkoli byly posuny časových pásem použity podle specifikace, neovlivnilo to datum/čas. Oba výsledné datum/časy mají stejnou hodnotu – změnil se pouze posun časového pásma.

Pokud to není to, co chcete, můžete přidat AT TIME ZONE 'UTC' do mixu, abyste nejprve převedli původní data na UTC, než budou převedena do požadovaného časového pásma.

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

Výsledek:

@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. Chyba MySQL #1071 - Zadaný klíč byl příliš dlouhý; maximální délka klíče je 767 bajtů

  2. Existují bezpečnostní rizika spojená s monitorováním Spotlight Cloudu?

  3. Hodnoty se v orákulu nezobrazují s úvodní nulou

  4. SQL Server 2017:Dostupné funkce v systému Linux