Podpora časového pásma v mssql-django

Tento článek vysvětluje, jak pole typu datum a čas s podporou časového pásma fungují se serverem SQL Server prostřednictvím backendu mssql-django a jak migrovat stávající data při povolení podpory časových pásem.

Jak funguje podpora časového pásma

Nastavení USE_TZ v Django v settings.py určuje, zda pole typu datum a čas obsahují informaci o časovém pásmu:

Setting Typ sloupce Behavior
USE_TZ=False datetime2 Ukládá naivní data a časy bez informací o časovém pásmu.
USE_TZ=True datetimeoffset Ukládá hodnoty data a času s informací o časovém pásmu a posunem od UTC.

Note

Django ve výchozím nastavení používá USE_TZ=False ve všech verzích, včetně Django 5.x a 6.0. Pokud váš projekt potřebuje podporu časového pásma, musíte explicitně nastavit USE_TZ=True ve svém settings.py. Další informace najdete v tématu Podpora časových pásem v Django . Mějte na paměti, že datetimeoffset obvykle používá více úložiště než datetime2 pro stejnou přesnost časového razítka, takže u velkých tabulek byste měli po migraci ověřit plány úložiště a dotazů.

Povolení podpory časového pásma

Nastavte USE_TZ=True ve svém settings.py:

USE_TZ=True
TIME_ZONE = "UTC"

Pokud USE_TZ je povoleno, Django ukládá všechny data a časy v UTC a převede je do místního časového pásma pro zobrazení.

mssql-django Od verze 1.7.2 backend také uvádí chování Django Now() do souladu s generováním SQL s podporou časových pásem, když USE_TZ=True.

Migrace existujících sloupců data a času

Pokud vaše aplikace Django měla sloupce DateTimeField před povolením USE_TZ=True, musíte ručně migrovat sloupce datetime2 na datetimeoffset a převést místní čas na UTC.

Backend mssql-django používá datetime2 jako podkladový typ sloupce pro DateTimeField, když USE_TZ=False. Povolení USE_TZ automaticky nepřevádí existující sloupce.

V následujících krocích nahraďte zástupné symboly:

  • <table-name>: Název tabulky obsahující sloupec.
  • <datetime-column>: Název sloupce, který chcete převést.
  • <offset>: Posun časového pásma existujících dat jako řetězec ve {+|-}HH:MM formátu (například '-05:00' pro USA – východ).

Ukázky kódu v tomto článku používají ukázkovou databázi AdventureWorks2025 nebo AdventureWorksDW2025, kterou si můžete stáhnout z domovské stránky Microsoft SQL Serveru pro ukázky a komunitní projekty .

Krok 1: Změna typů sloupců

V každé tabulce se sloupci datetime2 spusťte následující SQL. SQL Server implicitně převede hodnotu a přiřadí +00:00 posun:

ALTER TABLE <table-name>
ALTER COLUMN <datetime-column> DATETIMEOFFSET;

Krok 2: Převod na UTC

Jakmile je sloupec datetimeoffset, znovu označte každou hodnotu s původním posunem místního časového pásma a pak převeďte na UTC:

UPDATE <table-name>
SET <datetime-column> = TODATETIMEOFFSET(<datetime-column>, <offset>) AT TIME ZONE 'UTC';

TODATETIMEOFFSET nahradí část posunu hodnoty datetimeoffset , aby časové razítko odráželo původní místní čas. AT TIME ZONE 'UTC' poté převede výsledek na UTC.

Important

Jeden pevný posun funguje jenom v případech, kdy všechny zdrojové hodnoty sdílejí stejný posun. Pokud vaše data zahrnují přechody na letní a zimní čas, odvoďte posun podle data nebo použijte strategii převodu založenou na názvu časového pásma namísto použití jednoho konstantního posunu pro každý řádek.

SQL Server názvy časových pásem

Používejte názvy časových pásem systému Windows při převodu pomocí AT TIME ZONE. Běžné příklady:

Region SQL Server název časového pásma Data přechodu DST (2026)
USA – východ Eastern Standard Time 8. března – 1. listopadu
USA – střed Central Standard Time 8. března – 1. listopadu
Usa – Tichomoří Pacific Standard Time 8. března – 1. listopadu
standard UTC UTC Žádné (bez DST)
Evropa/Londýn GMT Standard Time 29. března – 25. října

Úplný seznam získáte dotazem na SQL Server:

SELECT name, current_utc_offset, is_currently_dst
FROM sys.time_zone_info
ORDER BY name;

Úplnou dokumentaci najdete v sys.time_zone_info .

Příklad: Převést americký východní čas na UTC (se zohledněním letního času)

Tento příklad používá existující AdventureWorks2025 tabulku schématu a ukazuje správné zpracování DST během migrace:

-- Test with a DST transition date (March 8, 2026)
SELECT TOP 10 SalesOrderID,
             CAST (OrderDate AS DATETIME2) AS OriginalDateTime2,
             (CAST (OrderDate AS DATETIME2) AT TIME ZONE 'Eastern Standard Time') AS EasternTime,
             (CAST (OrderDate AS DATETIME2) AT TIME ZONE 'Eastern Standard Time' AT TIME ZONE 'UTC') AS ConvertedToUtc
FROM Sales.SalesOrderHeader
WHERE MONTH(OrderDate) = 3 AND DAY(OrderDate) = 8
ORDER BY SalesOrderID;

Tip

Vždy otestujte převody časových pásem s daty, která zahrnují data přechodu DST. Předchozí testy dotazu ověřují 8. březen (posun času dopředu), kdy se východní čas mění z EST (UTC-5) na EDT (UTC-4).

Pokud chcete migrovat tabulky vaší aplikace, použijte stejný AT TIME ZONE postup převodu i pro své vlastní DateTimeField sloupce. Pro každou tabulku přidejte sloupec datetimeoffset a naplňte ho z existujícího sloupce:

ALTER TABLE [your_schema].[your_table] 
ADD [date_column_datetimeoffset] datetimeoffset NULL;

UPDATE [your_schema].[your_table]
SET [date_column_datetimeoffset] = CAST([old_date_column] AS DATETIME2) AT TIME ZONE 'Eastern Standard Time' AT TIME ZONE 'UTC';

Po ověření výsledků převodu odstraňte starý sloupec a přejmenujte nový:

ALTER TABLE [your_schema].[your_table]
DROP COLUMN [old_date_column];

EXECUTE sp_rename '[your_schema].[your_table].[date_column_datetimeoffset]', 'date_column', 'COLUMN';

Použijte název SQL Server Windows časového pásma, který odpovídá vaší zdrojové oblasti dat. Další informace najdete v tématu sys.time_zone_info.

Krok 3: Dokončení migrace Django

Po převodu sloupců databáze postupujte podle dokumentace Django k migraci projektu zahájeného před přidání podpory časového pásma.

Important

Tuto migraci spusťte u všech sloupců ve všech DateTimeField tabulkách. Pokud chybí kterýkoli sloupec, povede to k nesprávnému zpracování časového pásma u těchto polí.

Limitations

  • Časová pásma a časové zóny: Nejsou plně podporovány všechny operace zahrnující časová pásma a časové zóny. Další informace naleznete v tématu Omezení a nepodporované funkce v mssql-django.
  • Aritmetika s datetimes: Výkon pravé ruky a aritmetika s hodnotami datetime nemusí fungovat podle očekávání, pokud je povolena podpora časového pásma.