Data i czas
Data i czas
Generowanie czasu z liczby
Czas w Pythonie liczony jest jako liczba sekund od 1.01.1970, godz. 00:00:00 BST. Jest to aktualnie całkiem duża liczba 109. Aby na podstawie takich liczb rozszyfrować standardowe nazwy lat, miesięcy, dni, godziny, minuty i sekundy należy skorzystać z funkcji ctime() znajdującej się w bibliotece time.
import time print(time.ctime(0)) print(time.ctime(1000000000)) |
>>> Thu Jan 1 01:00:00 1970 Sun Sep 9 03:46:40 2001 |
Wynikiem tej funkcji jest zmienna tekstowa. Aby uzyskać czas zapisany w postaci krotki z nazwanymi wyrazami należy użyż funkcji localtime().
import time print(time.localtime(0)) print(time.localtime(1000000000)) |
>>> time.struct_time(tm_year=1970, tm_mon=1, tm_mday=1, tm_hour=1, tm_min=0, tm_sec=0, tm_wday=3, tm_yday=1, tm_isdst=0) time.struct_time(tm_year=2001, tm_mon=9, tm_mday=9, tm_hour=3, tm_min=46, tm_sec=40, tm_wday=6, tm_yday=252, tm_isdst=1) |
Poszczególne elementy tej krotki to rok,miesiąc,dzień,godzina,minuta,sekunda,dzień tygodnia (liczony od niedzieli z numerem 0, dzień roku (liczony od 0), oraz informacja czy jest to czas letni (0), czy zimowy(1).
Funkcje te pokazują, że początek czasu komputerowego miał miejsce o godzinie 1 w nocy, dnia 1 stycznia 1970 roku co trochę mija się z definicją poczatku czasu komputerowego. Warto wiedzieć, że obie te funkcje nie działają dla liczb ujemnych. Nie można przy ich pomocy wygenerować czasu przed 1 stycznia 1977 roku, godziną 1 w nocy.
Inną popularną funkcją zmieniającą liczbę sekund na formę ktrotki jest gmtime(). Jednak funkcja ta daje inne odpowiedzi.
import time print(time.gmtime(0)) print(time.gmtime(1000000000)) |
>>> time.struct_time(tm_year=1970, tm_mon=1, tm_mday=1, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=3, tm_yday=1, tm_isdst=0) time.struct_time(tm_year=2001, tm_mon=9, tm_mday=9, tm_hour=1, tm_min=46, tm_sec=40, tm_wday=6, tm_yday=252, tm_isdst=0) |
Spróbujemy wyjaśnić różnicę czasu jednej albo dwóch godzin dla tej funkcji w stosunki do ctime() i localtime().
print(1000000000//60, 1000000000 % 60) #liczba minut i sekund. print(16666666//60, 16666666 % 60) #liczba godzin i minut print(277777//24, 277777 % 24) #liczba dni i godzin |
>>> time.struct_time(tm_year=1970, tm_mon=1, tm_mday=1, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=3, tm_yday=1, tm_isdst=0) time.struct_time(tm_year=2001, tm_mon=9, tm_mday=9, tm_hour=1, tm_min=46, tm_sec=40, tm_wday=6, tm_yday=252, tm_isdst=0) |
109 sekund to 16666666 minut i 40 sekund. 16666666 minut to 277777 godzin i 46 minut. 277777 godzin to 11574 dni i 1 godzina. Łatwo sprawdzić, że róznica wskań czasu przez obie te funkcję wynosi 1 godzinę dla czasu zimowego i dwie godziny dla czasu letniego. Która jest właściwa?. Trzeba spojrzeć na zegarek (a najlepiej zegar systemowy) i użyć funkcji time() bez argumentów by uzyskać aktualny czas w sekundach, a następnie wykonać dla niego obie funkcje.
import time x=time.time() print(time.ctime(x)) print(time.gmtime(x)) |
Okazuje się, że funkcja ctime( ) pokazuje czas właściwy dla naszej strefy czasowej, a funkcja gmtime() dla strefu czasowej wokół południka 0 (Wielka Brytania, gdzie nie ma zmiany czasu). Świadczy o tym skrót BST (British Summer Time), który pojawia się w definicji początku czasu komputerowego, który zaczyna się na południku 0 z godziną 00:00:00, a dla stref czasowych z półkuli wschodniej o odpowiedni czas później.
Generowanie liczb z czasu
Funkcją odwrotną do localtime() jest time.mktime(y), której argument y musi być odpowiednio napisaną krotką złożoną z 9 liczb. Działanie tych funkcji pokazuje następujacy program:
import time y=2001, 9, 9, 3, 46, 40, -1, -1, -1 print(time.mktime(y)) |
>>> 1000000000.0 |
Krotka, będąca argumentem funkcji time.mktime() musi mieć specjalna strukturę. Pierwsza z liczb musi być większa lub równa 1970 i oznacza rok, druga jest numerem miesiąca, więc musi pochodzić z zakresu od 0 do 11. W tym jednak wypadku napisanie liczby ujemnej lub większej o 11 spowoduje korektę roku i wyznaczenie miesiąca odpowiedniego roku. Trzecia jest numerem dnia miesiąca, czwarta jest godziną, piąta minutą, szósta sekundą. Trzy ostatnie cyfry oznaczają numer dnia tygodnia (poniedziałek dostaje 0), numer dnia roku i oznaczenie czy jest to czas letni czy zimowy. W miejsce nieznanych liczb można wpisać -1. Wpisanie liczby spoza przewidywanego zakresu generuje błąd.
Użycie poniższego programu pozwala na szybkie wyliczenie dla kalendarzowej daty i zegarowej godziny dodatkowych informacji: jaki był to dzień tygodnia (poniedziałek ma numer 0), który to dzień w roku (licząc od dnia 0) i czy obowiązywał wtedy czas letni (1), czy zimowy (0).
import time y=2010, 7, 15, 10, 0, 0, -1, -1, -1 x=time.mktime(y) print(x) print(time.localtime(x)) |
>>> 1279180800.0 time.struct_time(tm_year=2010, tm_mon=7, tm_mday=15, tm_hour=10, tm_min=0, tm_sec=0, tm_wday=3, tm_yday=196, tm_isdst=1) |
W miejsce miesiąca, dnia, godziny, minuty i sekundy można wstawić liczby ujemne lub spoza wyznaczonego zakresu. Cofają lub przyśpieszają one czas o tę liczbę godzin, minut, sekund, która jest po znaku – lub poza standardowym zakresem.
Funkcje pokazujące czas w zrozumiałych formatach
Zarówno liczba sekund jak i krotka generowana przez funkcje ctime() i localtime() sa mało czytelne. Należy format krotki przekształcić na bardziej zrozumiały tekst.
Szybki sposób by zapisać czas zapisany w postaci 9-elementowej krotki w bardziej przystępnej formie polega na zastosowaniu funkcji asctime().
import time y=2010, 7, 15, 10, 0, 0, -1, 0, -1 print(time.asctime(y)) |
>>> Sun Jul 15 10:00:00 2010 |
Więcej możliwości daje funkcja strftime() z biblioteki time. Pozwala na wybranie różnych informacji o podanym czasie w formie tekstowej w dowolnie przyjety sposób. Jej argumentami może być 22 różnych symboli, które można używać osobno jak i w dowolnych zestawach.
from time import strftime y=2010, 7, 15, 10, 0, 0, -1, 0, -1 print(strftime(‘%a %A’,y)) # nazwa dnia tygodnia print(strftime(‘%b %B’,y)) # nazwa miesiąca print(strftime(‘%c’,y)) # data i czas print(strftime(‘%d’,y)) # numer dnia miesiąca” print(strftime(‘%H’,y)) # numer godziny od 24:00 print(strftime(‘%I’,y)) # numer godziny od 12:00 print(strftime(‘%j’,y)) # numer dnia roku print(strftime(‘%m’,y)) # numer miesiąca print(strftime(‘%M’,y)) # minuta print(strftime(‘%p’,y)) # czy AM, czy PM print(strftime(‘%S’,y)) # sekunda print(strftime(‘%U’,y)) # numer tygodnia w roku print(strftime(‘%w %W’,y)) # dzień tygodnia i numer tygodnia w roku print(strftime(‘%x’,y)) # data (misiąc\dzień\dwie ostatnie cyfry roku) print(strftime(‘%X’,y)) # czas print(strftime(‘%y %Y’,y)) # rok print(strftime(‘%z %Z’,y)) # strefa czasowa kod i nazwa |
>>> Sun Sunday Jul July Sun Jul 15 10:00:00 2010 15 10 10 001 07 00 AM 0001 0 00 07/15/10 10:00:0010 2010 +0200 Środkowoeuropejski czas letni |
Poprzez odpowiednia kompozycję odpowiednich informacji możemy uzyskać tekstowy zapis czasu w dowolnej formie.
from time import strftime y=2010, 7, 15, 10, 0, 0, -1, 0, -1 print(strftime(‘%A %d/%m/%Y’,y)) print(strftime(‘%d-%m-%Y %H:%M:%S’,y)) |
>>> Sunday 15/07/2010 15-07-2010 10:00:00 |
Generowanie czasu aktualnego
Aby uzyskać aktualny czas w formie liczby sekund wystarczy użyć funkcji time z biblioteki time
import time print(time.time()) |
>>> 1708015049.7253778 |
Czas podawany jest z dokładnością do nanosekund, a ściślej taktowania zegara systemowego.
Funkcja strftime() bez drugiego argumentu domyślnie przyjmuje czas aktualny. Można za jej pomocą dowolnie komponować zapis aktualnego czasu. Przykładowo datę dzień/miesiąc/rok, dzień-miesiąc-rok, lub dzień.miesiąc.rok uzyskamy pisząc:
from time import strftime print(strftime(‘%d/%m/%Y’)) print(strftime(‘%d-%m-%Y’)) print(strftime(‘%d.%m.%Y’)) |
>>> 15/02/2024 15-02-2024 15.02.2024 |
Obliczanie odstępu czasowego między dwoma chwilami
Przeliczenie na liczbę sekund kilku kolejnych dat pozwala na obliczenie odstępu czasowego między tymi datami.
import time y1=2011, 7, 15, 0, 0, 0, -1, -1, -1 y2=2012, 3, 11, 0, 0, 0, -1, -1, -1 x1=time.mktime(y1) x2=time.mktime(y2) print(x2-x1) #czas w sekudach print((x2-x1)/60) #czas w minutach print((x2-x1)/(60*60)) #czas w godzinach print((x2-x1)/(24*60*60)) #czas w dniach |
>>> 20739600.0 345660.0 5761.0 240.04166666666666 |
Pomimo, że odstęp w dniach spodziewaliśmy się, że będzie wyrażony liczbą całkowitą, Python uwzględnił przy wyliczaniu sekund godzinę związaną ze zmianą czasu z zimowego na letni. Ostatecznie 1/24 zostało dodane do wyniku w dniach.
Biblioteka calendar
W bibliotece time znajduje się jeszcze dużo funkcji pozwalających na wyliczanie czasu wielu komputerowych akcji, np. tzw. taktowania zegara systemowego, z jaka dokładności obliczany jest tam czas albo czas wykonania standardowych operacji na procesorze. Funkcje te pozwalają na diagnozowanie pracy sprzętu komputerowego i są potrzebne programistom, nie biologom. Ciekawsze opcje mają biblioteki włączane przez świat programistów do Pythona wykorzystujące funkcje biblioteki time. Np. w bibliotece calendar znajduje się funkcja calendar.month(x,y), która pozwala na wyświetlenie układu dni w tygodniu w miesiącu y w roku x. Działanie innych funkcji z tej biblioteki można prześledzić wykonując następujący program.
import calendar #print(calendar.calendar(1700,w=5,l=2,c=3)) #Kalendarz dla podanego roku z nazwami miesięcy. print(calendar.month(2018, 1)) #Kalendarz dla podanego roku i miesiąca print(calendar.monthcalendar(2018,2)) #Wykaz kolejnych dni danego miesiąca z zaznaczeniem całych tygodni (od poniedziałku) print(calendar.monthrange(2018,2)) #Liczba dni do pierwszego w tygodniu gdy zaczyna się miesiąc i liczba dni miesiaca print(calendar.weekday(2018,2,1)) #Numer dnia tygodnia odpowiadający danej dacie, poniedziałek ma numer 0 print(calendar.isleap(1700)) #Sprawdzenie, czy podany rok jest przestępny print(calendar.leapdays(1700,2018)) #Obliczenie liczby lat przestępnych między podanymi latami. |
>>> >>> %Run A.py January 2018 Mo Tu We Th Fr Sa Su 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31[[0, 0, 0, 1, 2, 3, 4], [5, 6, 7, 8, 9, 10, 11], [12, 13, 14, 15, 16, 17, 18], [19, 20, 21, 22, 23, 24, 25], [26, 27, 28, 0, 0, 0, 0]] (3, 28) 3 False 77 |
Jak widać calendar radzi sobie z latami mniejszymi od 1970 roku. Musi być to jednak rok dany cyfrą dodatnią. Wszelkie obliczenia przy użyciu tej biblioteki możemy wykonywać począwszy od roku 1 naszej ery.