DatetimeTypesInSQL_00

Typy daty i czasu w SQL Server

Artykuł ten jest częścią serii Od 0 do TSQL którą znajdziesz tutaj.

Po typach tekstowych oraz liczbowych przyszła pora na omówienie typów daty i czasu. Część z Was może pomyśleć, iż datę i czas można przechowywać jako wartość liczbową? Generalnie jest to możliwe – pozbawiamy się wtedy jednak możliwości jakie oferuje użytkowanie typów przeznaczonych do tego typu danych.

W SQL Server mamy wbudowanych wiele typów związanych z datą i czasem, oto one:

  • date
  • datetime
  • datetime2
  • smalldatetime
  • time
  • datetimeoffset

Najprostszym z nich jest wspomniany na liście typ date. Jak można się domyśleć typ ten przechowuje datę. W ramach obiektu o tym typie możemy przechowywać daty od 0001-01-01 do 9999-12-31, gdzie jeden taki wpis zajmuje zawsze 3 bajty. Jeżeli chodzi
o format danych wstawianych do takiego pola to zależy on od ustawień serwera – jednak jeżeli podamy wartość daty w formacie ‘YYYYMMDD’ to zostanie on dostosowany do ustawień lokalnych – warto więc zapamiętać ten format i stosować go w większości przypadków.

Kolejnym równie prostym typem danych jest datetime. Jak sama nazwa wskazuje przechowuje on nie tylko datę, ale również czas. Pozwala na przechowywanie dat pochodzących z zakresu od 1753-01-01 do 9999-12-31 wraz z dowolną godziną aż do części milisekundowych. Typ ten zajmuje aż 8 bajtów co jest dosyć dużym rozmiarem.
W przypadku gdy nie jest nam potrzebna tak duża dokładność jaką oferuje nam datetime to warto zastosować bardzo zbliżony typ tj.  smalldatetime, który zajmuje 4 bajty ale pozwala na przechowywanie dat o dużo mniejszym zakresie tj. od 1900-01-01 do 2079-06-06. Jeżeli chodzi o czas to z smalldatetime tym wiąże się również bardzo ciekawa właściwość, którą postaram się zobrazować poniżej.

W ramach dowolnej bazy zadeklarujmy sobie zmienną przypiszmy do niej pełną datę i czas oraz wyświetlmy jej zawartość.

DECLARE @smalldatetime SMALLDATETIME

SET @smalldatetime='20150101 23:51:51'

PRINT	@smalldatetime

Jaką wartość wyświetli nam SQL Server? Dosyć nieoczekiwaną:

Jan  1 2015 11:52PM

Jak widać nie ma zdefiniowanych części sekundowych godziny, a część minutowa została zaokrąglona. Jest to normalne zachowanie tego typu danych, który zawsze należy mieć w tyle głowy w momencie gdy chcemy go użyć.

Co natomiast w przypadku gdy nie jest dla nas istotna dla nas data a jedynie czas? SQL Server daje nam możliwość przechowywania samego czasu i obok wspomnianych typów  mamy również typ time pozwalający przechowywać czas w oparciu o zegar 24 godzinny, aż do poziomu nanosekund. Poziom części sekund oczywiście jesteśmy w stanie kontrolować podając go jako parametr tj. np. time(7) oznacza właśnie poziom nanosekund – najbardziej szczegółowy. W zależności od szczegółowości typ ten zajmuje określoną ilość miejsca zgodnie z tabelą:

Zdefiniowany typ (precyzja,skala) Ilość bajtów
time (16,7) 5
time(0) (8,0) 3
time(1) (10,1) 3
time(2) (11,2) 3
time(3) (12,3) 4
time(4) (13,4) 4
time(5) (14,5) 5
time(6) (15,6) 5
time(7) (16,7) 5

Typ ten ma szczególne zastosowanie w momencie gdy chcemy przechowywać bardzo szczegółowe dane godzinowe, lub gdy chcemy z jakichś powodów oddzielić godzinę od daty. Podobnym pod względem dokładności godziny jest typ datetime2, który jest standardowym połączeniem typów datetime i time, a co za tym idzie również pozwala na zdefiniowanie poziomu szczegółowości godziny i zajmuje maksymalnie do 8 bajtów.

Ostatnim typem jaki sobie wyjaśnimy jest typ datetimeoffset, który pozwala na zapis daty i czasu wraz z uwzględnieniem strefy czasowej.  Wstawiając wartości do obiektu możemy użyć następującego domyślnego formatu YYYY-MM-DD hh:mm:ss[.nnnnnnn] [{+|-}hh:mm] czyli np.  ‘2015-12-31 23:59:10 +01:00’ oznacza przesunięcie o 1 godzinę do przodu w stosunku do UTC czyli standardowego czasu europejskiego. Przesunięcie może być zdefiniowane jako godzina oscylująca od -14:00 do +14:00. Typ ten jest bardzo pomocny w przypadku gdy dane w naszej bazie obejmują różne strefy czasowe, w innym wypadku powinniśmy go unikać gdyż posiada on dokładność taką jak datetime2 powiększoną właśnie o strefy czasowe i zajmuje w zależności od szczegółowości od 8 do 10 bajtów. W następnym artykule w ramach serii zajmiemy się funkcjami dostępnymi w ramach SQL Server, które pozwalają operować na konkretnych wartościach związanych z typami danych – ZAPRASZAM!

4 Comments

  1. Dzień Dobry
    a jak sformatować datę , żeby była wyświetlana w takim formacie i była liczbą?
    2019-08-05 12:17

    (select top 1 (CAST(CAST (TZ.DATACZAS_DO as date) as varchar(10)))+’ ‘+(CAST(CAST (TZ.DATACZAS_DO as time) as varchar(5))) from T_TACHO_ZDARZENIA TZ with(nolock) where tz.ID_KIEROWCY = kierowcy.id_kierowcy order by tz.DATACZAS_DO DESC) as [Ostatnia_data_logowania]
    ale to mi daje tekst 🙂

    Dzięki za info

    • Witam,

      tą datę chce Pan mieć jako liczbę? 201908051217? jeśli tak to polecam zapoznać się z funkcją FORMAT, która co prawda zwraca tekst ale można to później formatować jako liczbę.

Leave a Reply