15. diel - Dátum a čas v Pythone druhýkrát - Knižnica datetime
V minulej lekcii, Dátum a čas v Pythone , sme si predstavili knižnice time
a calendar
.
V nasledujúcom tutoriále objektovo orientovaného programovania v
Pythone sa pozrieme na prácu s modulom datetime
, ktorý
sa vedľa modulov time
a calendar
používa pre prácu
s dátumom a časom a podporuje príjemnejší, objektový prístup. Oproti
knižnici time
je datetime
oveľa bohatší a ponúka
širšiu paletu funkcií a vlastností. Súčasne ale tiež platí, že mnoho
funkcií (metód) majú obe knižnice buď priamo spoločných (názvom,
syntaxou aj výstupom), alebo sa len veľmi mierne líšia. V lekcii ich teda
nebudeme opakovať a viac sa zameriame viac na objektový prístup k dátumu a
času.
Knižnica datetime
Knižnica datetime
pracuje s vlastnými špecializovanými
datetime
objektmi. To nám ľahko umožní od seba jednotlivé
dáta napríklad odčítať alebo ich navzájom porovnávať bez nutnosti
zaoberania sa počtom sekúnd od roku 1970 alebo indexmi vo výstupe vo forme
tuple. Teraz si ukážeme, ako sa tieto objekty zakladajú a ako s nimi budeme
ďalej pracovať v jednotlivých moduloch.
Trieda datetime
Veľmi významnou triedou v tejto knižnici je rovnomenná trieda
datetime
a jej opäť rovnomenná:-) metóda
datetime()
. Tú budeme v praxi používať na vytváranie
inštancií, s ktorými budeme ďalej pracovať. Tiež poskytuje užitočné
metódy, ktoré budeme hojne využívať.
Bežnou konvenciou, ktorú dodržiavame aj v našich
tutoriáloch, je pomenovanie triedy veľkým písmenom, a teda by sme mali
triedu pomenovať Datetime
. Vývojári Pythona bohužiaľ na
konvencie v názvoch modulov a tried často príliš neberú ohľad. Aby náš
text lekcie zodpovedal skutočnému kódu, budeme na triedu odkazovať ako na
datetime
s malým počiatočným písmenom. Inak by sa text lekcie
od kódu líšil a bolo by to mätúce.
Metódy triedy datetime
Pozrime sa teraz na dôležité metódy, ktoré nám trieda
datetime
poskytuje. Ako sme už spomenuli v úvode lekcie, mnoho
metód je rovnakých alebo veľmi podobných s funkciami modulu
time
.
Metóda datetime()
Metóda datetime()
prijíma ako argumenty v danom poradí
údaje: rok, mesiac, deň, hodina, minúta, sekunda a mikrosekunda. Vytvorme si
inštanciu dátumu a času z určitého roku, mesiaca a dňa:
from datetime import datetime # Pro jednodušší kód si importujeme rovnou třídu Datetime.
# Vyhneme se tím opakovaným zápisům datetime.datetime(...).
datum = datetime(2023, 10, 23)
print(datum)
Metóda now()
Metóda now()
nám jednoducho umožní získať aktuálny dátum
a čas:
from datetime import datetime
dnes = datetime.now()
print(dnes)
Metóda vytvorí inštanciu triedy datetime
, v ktorej sú
uložené aktuálne informácie k dátumu. K jednotlivým údajom sa dostaneme
veľmi ľahko a to pomocou atribútov year
, month
,
day
, hour
, minute
a
second
:
from datetime import datetime
dnes = datetime.now()
print("Datum:")
print(f"Rok: {dnes.year}")
print(f"Měsíc: {dnes.month}")
print(f"Den: {dnes.day}")
print(f"Čas: {dnes.hour}:{dnes.minute}:{dnes.second}")
Metóda weekday()
Metóda, ktorú voláme na inštanciu triedy datetime
, nám
zistí deň v týždni, ku ktorému táto inštancia patrí. Skúsme si ju
zavolať na aktuálnom dátume a čase:
from datetime import datetime
dnes = datetime.now()
# Seznam dnů v týdnu
dny_v_tydnu = ["pondělí", "úterý", "středa", "čtvrtek", "pátek", "sobota", "neděle"]
den = dny_v_tydnu[dnes.weekday()]
print(f"Dnes je {den}.")
V tejto metóde sa pre nás ukrýva mnoho možností, a je iba na nás, aký formát na získavanie dátumu a času si zvolíme.
Knižnica datetime
okrem iného obsahuje napríklad metódy
strftime()
a strptime()
. Tieto metódy (a ďalšie)
sú prakticky identické s rovnomennými funkciami z modulu time
,
ktorými sme sa zaoberali v lekcii Dátum a čas v Pythone. Na
porovnanie je najlepšie nahliadnuť do oficiálnej dokumentácie knižnice
datetime.
Práca s dátumom
Práca s dátami je jednou z najčastejších úloh v programovaní. Či už
potrebujeme porovnať dve dáta alebo spočítať počet dní medzi nimi,
knižnica datetime
nám ponúka efektívne nástroje na tieto
úlohy. Výhodou knižnice datetime
je jej objektový prístup k
reprezentácii času a dátumu. Vďaka tomu, že všetky dáta ukladáme ako
inštancie tej istej triedy, máme teda možnosť vykonávať s dátami rôzne
aritmetické operácie, ako je sčítanie a odčítanie, alebo porovnávať
dáta medzi sebou. V tejto kapitole sa pozrieme na niekoľko základných
operácií a funkcií, ktoré nám datetime
ponúka na prácu s
dátami, a ukážeme si, ako ich efektívne využiť v praxi.
Aritmetické operácie s dátumom
Najprv sa zameriame na základné matematické operácie ako sú sčítanie a odčítanie:
from datetime import datetime
dnes = datetime.now() # založíme aktuální datum
tehdy = datetime(2000, 1, 1) # založíme datum 1.1.2000
ubehly_cas = dnes - tehdy # odečteme data od sebe
print(ubehly_cas)
V tomto prípade premenná ubehly_cas
obsahuje počet dní,
hodín, minút a sekúnd, ktoré ubehli od začiatku 3. tisícročia do
dnešného dňa. Za podobným účelom máme ešte k dispozícii metódu
total_seconds()
, ktorá vráti počet sekúnd ubehnutých v danom
intervale.
Porovnávanie
Dve dáta môžeme medzi sebou aj porovnávať a to obyčajnými operátormi, ktoré používame pri porovnávaní čísel:
from datetime import datetime
dnes = datetime.now()
tehdy = datetime(2000, 1, 1)
print(dnes > tehdy) # vrátí True
print(dnes == tehdy) # vrátí False
Zmena vytvoreného dátumu
Ak potrebujeme rýchlo a ľahko zmeniť už vytvorený dátum, použijeme
metódu replace()
. Zvýšime si rok a deň na objekte
datetime
o 1
:
from datetime import datetime
dnes = datetime.now()
zmena_roku = dnes.replace(year = dnes.year + 1)
zmena_dne = dnes.replace(day = dnes.day + 1)
print(f"Přidáme rok navíc a budeme mít rok {zmena_roku.year}.")
print(f"Přidáme den navíc a budeme mí {zmena_dne.day}.{dnes.month}.")
Metóda replace()
funguje na akomkoľvek časovom objekte –
len v nej musíme presne špecifikovať, čo chceme meniť na akú hodnotu. Ide
iba o zmenu hodnoty už založenej premennej.
Ak je dnes.day
posledný deň mesiaca (napr. 31.
januára alebo 30. apríla), pridanie jedného dňa spôsobí
ValueError
.
Podobné problémy však rieši trieda timedelta
. Pozrime sa na
ňu.
Trieda timedelta
Pre ďalšie možnosti práce s časom je tu trieda timedelta
.
Trieda timedelta
nám umožňuje vyjadriť časový interval, čo
môže zahŕňať dni, sekundy, mikrosekundy a podobne. S inštanciami
timedelta
je možné podobne ako v prípade triedy
datetime
vykonávať rôzne aritmetické operácie, napríklad
pridávať ich k inštanciám datetime
alebo odčítať ich od
seba. Pokiaľ od seba dve dáta napríklad odčítame, získame inštanciu
triedy timedelta
, čo nie je konkrétny dátum, ale interval
(rozdiel) medzi nejakými dvoma dátami. Tento objekt si založíme a ľahko
zistíme, aký deň bude o 10 dní:
from datetime import datetime
from datetime import timedelta
dnes = datetime.now()
deset_dnu = timedelta(10) # vytvoříme objekt timedelta s posunem o 10 dní
za_10_dni = dnes + deset_dnu
pred_10_dny = dnes - deset_dnu
print(f"Dnes je: {dnes}")
print(f"Za 10 dní bude: {za_10_dni}")
print(f"Před 10 dny bylo: {pred_10_dny}")
Trieda timedelta
tiež rieši problém s prechodom z mesiaca na
mesiac. Ak interval presiahne plný (alebo minimálny) počet dní v danom
mesiaci, trieda automaticky prejde na ďalší (predchádzajúci) mesiac v
poradí.
Konštruktor timedelta()
nemusíme vždy použiť s celými
dňami. Pokiaľ chceme pracovať s inou hodnotou, máme tú možnosť. Pri
zakladaní objektu timedelta
máme možnosť navoliť mnoho
argumentov. Ak explicitne neuvedieme názvy argumentov, tak v uvedenom
poradí:
- days,
- seconds,
- microseconds,
- milliseconds,
- minutes,
- hours,
- weeks.
timedelta
, je dobré si zvyknúť explicitne uvádzať
mená argumentov. Zvýšime tým čitateľnosť kódu a eliminujeme potenciálny
zmätok:
interval = timedelta(weeks=2, days=3, hours=1)
Trieda timedelta
bohužiaľ nemá v argumentoch
dostupný počet rokov a mesiacov, pretože rok ani mesiac nie sú plnohodnotné
časové jednotky a nemajú pevne daný počet dní (niektoré roky sú
prestupné).
Orezanie dátumu o čas
Všetky metódy, ktoré sme si doteraz spomenuli, pracujú s objektmi
datetime
(dátum a čas). Ak by sme chceli využívať iba dátum,
je vhodné namiesto tohto použiť objekt date
. Ten nenesie
informáciu o čase, ktorý by nám inak mohol znepríjemňovať potrebné
porovnávanie. Objekt date
získame z triedy datetime
pomocou metódy date()
:
from datetime import date
from datetime import timedelta
dnes = date.today()
print(f"Dnešní datum: {dnes}")
print(f"Za 10 dní bude: {dnes + timedelta(10)}")
print(f"Před 10 dny bylo: {dnes - timedelta(10)}")
Nie je na tom nič zložité. Jediná zmena od datetime
je v
použití metódy today()
, ktorá priamo nahrádza
now()
. Všetky metódy používané vyššie v lekcii sú s týmto
formátom úplne kompatibilné. Pokiaľ teda vo svojich programoch nepotrebujeme
časové informácie, môžeme ich pomerne ľahko vynechať.
Súbežné použitie
time
a datetime
Pokiaľ sa rozhodneme v jednom programe využívať súčasne moduly
time
a datetime
, na prvý pohľad nám to prinesie
určité výhody. Najmä širokú škálu funkcií a metód oboch modulov.
Avšak je tu jedno veľké „ale“.
Oba moduly majú, ako sme už spomenuli, mnoho funkcií a metód s rovnakým
názvom, napríklad strftime()
. Pokiaľ oba moduly naimportujeme
kompletne pomocou import time
a import datetime
,
budeme musieť uvádzať, z ktorého modulu chceme danú funkciu alebo metódu
používať. Napríklad takto - time.strftime()
alebo
datetime.datetime.strftime()
. To povedie k veľmi neprehľadnému
kódu a pravdepodobne aj k zbytočným chybám. Preto je veľmi vhodné pri
importoch použiť aliasy alebo triedy importovať priamo:
from datetime import datetime as dt from datetime import timedelta
Vďaka tomu si budeme istí, akú funkciu či metódu z akého modulu skutočne voláme.
V nasledujúcom kvíze, Kvíz - Dátum a čas v Pythone, si vyskúšame nadobudnuté skúsenosti z predchádzajúcich lekcií.