Wprowadzenie
Dane mogą być reprezentowane w różnych formach – i wygodny sposób przedstawiania dat i godzin smyczki. Jednak aby pracować z tymi datami i godzinami w sposób arytmetyczny (taki jak obliczanie różnic czasowych, dodawanie lub odejmowanie czasu itp.) – musimy je przekonwertować na datetime
obiekt.
Jedno z najczęstszych źródeł datetime w formacie łańcuchowym to interfejsy API REST, które zwracają łańcuchy agnostyczne, które możemy następnie przekonwertować na inne formaty.
Dodatkowo – strefy czasowe są częstym problemem podczas pracy z obiektami datetime, więc będziemy musieli o tym pomyśleć również podczas konwersji.
W tym przewodniku – przyjrzymy się, jak przekonwertować ciąg znaków data/czas na a
datetime
obiekt w Pythonie, używając wbudowanegodatetime
moduł, ale także moduły innych firm, takie jakdateutil
,arrow
i Maya, uwzględniając strefy czasowe.
Konwersja ciągów przy użyciu datetime
Połączenia data i godzina moduł składa się z trzech różnych typów obiektów: date
, time
, datetime
, date
obiekt posiada datę, time
trzyma czas i datetime
zawiera zarówno datę, jak i czas!
import datetime
print(f'Current date/time: {datetime.datetime.now()}')
Uruchomienie tego kodu spowoduje:
Current date/time: 2022-12-01 10:27:03.929149
Jeśli nie podano niestandardowego formatowania, używany jest domyślny format ciągu, tj. format „2022-12-01 10:27:03.929149” to ISO 8601 format (RRRR-MM-DDTHG:MM:SS.mmmmmm). Jeśli nasz ciąg wejściowy do utworzenia pliku datetime
obiekt jest w tym samym formacie ISO 8601 lub jeśli znasz format, który otrzymasz z góry, możemy łatwo przeanalizować go do datetime
obiekt:
import datetime
date_time_str = '2022-12-01 10:27:03.929149'
date_time_obj = datetime.datetime.strptime(date_time_str, '%Y-%m-%d %H:%M:%S.%f')
print('Date:', date_time_obj.date())
print('Time:', date_time_obj.time())
print('Date-time:', date_time_obj)
Uruchomienie spowoduje wydrukowanie daty, godziny i daty i godziny:
Date: 2022-12-01
Time: 10:27:03.929149
Date-time: 2022-12-01 10:27:03.929149
Tutaj używamy strptime()
metoda, która przyjmuje dwa argumenty:
- Data w formacie ciągu
- Format pierwszego argumentu
Określenie formatu w ten sposób sprawia, że parsowanie jest znacznie szybsze datetime
nie musi samodzielnie próbować interpretować formatu, co jest znacznie droższe obliczeniowo. Zwracana wartość jest typu datetime
.
W naszym przykładzie "2022-12-01 10:27:03.929149"
jest ciągiem wejściowym i "%Y-%m-%d %H:%M:%S.%f"
jest formatem naszego ciągu daty. zwrócony datetime
wartość jest przechowywana jako date_time_obj
.
Ponieważ jest to datetime
obiekt, możemy nazwać date()
i time()
metody bezpośrednio na nim. Jak widać na wyjściu, drukuje część „daty” i „czasu” ciągu wejściowego!
Formatuj tokeny
Warto poświęcić chwilę, aby to zrozumieć formatować tokeny - "%Y-%m-%d %H:%M:%S.%f"
sprzed.
Każdy token reprezentuje inną część daty i godziny, np. dzień, miesiąc, rok, dzień miesiąca lub tygodnia itp. lista obsługiwanych tokenów jest wystarczająco obszerny, aby umożliwić różne formatowanie. Niektóre z powszechnie używanych, z których również korzystaliśmy wcześniej, to:
%Y
: Rok (4 cyfry)%m
: Miesiąc%d
: Dzień miesiąca%H
: Godzina (24 godziny)%M
: Minuty%S
: Sekundy%f
: Mikrosekundy
Uwaga: Oczekuje się, że wszystkie te tokeny, z wyjątkiem roku, będą wypełnione zerami (tzn. sierpień jest ósmym miesiącem i są wypełnione zerami, aby 08
).
Używanie tokenów formatu strptime() do konwersji ciągu znaków na inny format daty i godziny
Jeśli format łańcucha jest znany, można go łatwo przeanalizować do a datetime
obiekt używający strptime()
. Rzućmy okiem na nietrywialny przykład, który tłumaczy z jednego formatu na inny:
import datetime
date_time_str = 'Jul 17 2022 9:20AM'
date_time_obj = datetime.datetime.strptime(date_time_str, '%b %d %Y %I:%M%p')
print('Date:', date_time_obj.date())
print('Time:', date_time_obj.time())
print('Date-time:', date_time_obj)
Ciąg wejściowy miał jeden format – „17 lipca 2022 r. 9:20”. Znając ten format, zmapowaliśmy elementy składowe do formatu ISO 8601 i przekonwertowaliśmy go na format a datetime
obiekt:
Date: 2022-07-17
Time: 09:20:00
Date-time: 2022-07-17 09:20:00
Oto krótka lista typowych dat i godzin w formacie łańcuchowym oraz odpowiadających im formatów dla strptime()
:
"Jun 28 2018 at 7:40AM" -> "%b %d %Y at %I:%M%p"
"September 18, 2017, 22:19:55" -> "%B %d, %Y, %H:%M:%S"
"Sun,05/12/99,12:30PM" -> "%a,%d/%m/%y,%I:%M%p"
"Mon, 21 March, 2015" -> "%a, %d %B, %Y"
"2018-03-12T10:12:45Z" -> "%Y-%m-%dT%H:%M:%SZ"
Możesz analizować ciąg daty i godziny w dowolnym formacie — pod warunkiem, że używasz poprawnego ciągu tokenów formatu dla otrzymywanych danych wejściowych.
Konwertuj ciąg znaków na datę i godzinę ze strefami czasowymi
Obsługa dat i godzin staje się bardziej złożona w przypadku stref czasowych. Wszystkie powyższe przykłady do tej pory są naiwne w stosunku do strefy czasowej. Są to tzw naiwne obiekty datetime.
Jednakże datetime
obiekty zawierają pole dokładnie do przechowywania danych związanych ze strefą czasową – tzinfo
:
import datetime as dt
dtime = dt.datetime.now()
print(dtime)
print(dtime.tzinfo)
Połączenia tzinfo
pole ma być a datetime.timezone
obiekt, oznaczający informacje o strefie czasowej. Jego None
domyślnie i oznacza, że obiekt datetime jest naiwny w strefie czasowej. Bardzo popularną zewnętrzną biblioteką do obsługi stref czasowych jest pytz
. Możesz ustawić PyTz obiekty jako tzinfo
pole też.
Jeśli jeszcze go nie masz – zainstaluj poprzez:
$ pip install pytz
Korzystając z PyTz, możemy utworzyć kotwicę dla dat i godzin uwzględniających strefę czasową, takich jak UTC:
import datetime as dt
import pytz
dtime = dt.datetime.now(pytz.utc)
print(dtime)
print(dtime.tzinfo)
Wyjście:
2022-12-01 02:07:41.960920+00:00
UTC
Nie jest już 11:2, ale XNUMX:XNUMX, ponieważ przesunęliśmy strefę czasową o kilka godzin wstecz! Ten zmienia strefę czasową daty i godziny.
+00:00
jest różnicą między wyświetlanym czasem a czasem UTC jako globalną kotwicą koordynacji. Ustawiliśmy czas na UTC, więc przesunięcie jest takie 00:00
. Jest obiekt rozpoznający strefę czasową.
Podobnie możemy przełączać interpretację tej samej daty i godziny między strefami czasowymi. Przekonwertujmy ciąg, taki jak „2022-06-29 17:08:00” na datę i godzinę, a następnie zlokalizować ustaw go na strefę czasową „America/New_York”:
import datetime as dt
import pytz
date_time_str = '2022-06-29 17:08:00'
date_time_obj = dt.datetime.strptime(date_time_str, '%Y-%m-%d %H:%M:%S')
timezone = pytz.timezone('America/New_York')
timezone_date_time_obj = timezone.localize(date_time_obj)
print(timezone_date_time_obj)
print(timezone_date_time_obj.tzinfo)
Uwaga: Localization zamienia naiwną strefę czasową datetime na datetime uwzględniającą strefę czasową i traktuje strefę czasową jako lokalną. Więc datetime pozostaje taka sama, ale biorąc pod uwagę inną strefę czasową, nie reprezentuje już tego samego punktu w czasie niezwiązanego ze strefami czasowymi.
Dostajemy to samo wartość daty i godziny, przesunięte o -04: 00 w porównaniu do czasu UTC:
2022-06-29 17:08:00-04:00
America/New_York
17:08 w Tokio nie jest w tym samym momencie co 17:08 w Nowym Jorku. 17:08 w Tokio to 3:08 w Nowym Jorku.
Jak znaleźć wszystkie kody/aliasy stref czasowych?
Aby znaleźć wszystkie dostępne strefy czasowe, sprawdź all_timezones
pole, które jest listą wszystkich dostępnych stref czasowych:
print(f'There are {len(pytz.all_timezones)} timezones in PyTzn')
for time_zone in pytz.all_timezones:
print(time_zone)
Zapoznaj się z naszym praktycznym, praktycznym przewodnikiem dotyczącym nauki Git, zawierającym najlepsze praktyki, standardy przyjęte w branży i dołączoną ściągawkę. Zatrzymaj polecenia Google Git, a właściwie uczyć się to!
There are 594 timezones in PyTz
Africa/Abidjan
Africa/Accra
Africa/Addis_Ababa
Africa/Algiers
Africa/Asmara
Africa/Asmera
...
Zmień strefę czasową Datetime
Możemy przekonwertować strefę czasową uwzględniającą strefę czasową datetime
obiekt z jednego regionu do drugiego, zamiast lokalizować naiwną strefę czasową datetime przez pryzmat jakiejś strefy czasowej.
Różni się to od lokalizacji, ponieważ lokalizacja reprezentuje inny punkt w czasie, ale przekształcenie strefy czasowej obiektu reprezentuje ten sam punkt w czasie, z innej perspektywy:
import datetime as dt
import pytz
timezone_nw = pytz.timezone('America/New_York')
nw_datetime_obj = dt.datetime.now(timezone_nw)
timezone_london = pytz.timezone('Europe/London')
london_datetime_obj = nw_datetime_obj.astimezone(timezone_london)
print('America/New_York:', nw_datetime_obj)
print('Europe/London:', london_datetime_obj)
Najpierw stworzyliśmy jeden obiekt datetime z bieżącym czasem i ustawiliśmy go jako strefę czasową „America/New_York”. Następnie za pomocą astimezone()
metoda, przekonwertowaliśmy to datetime
do strefy czasowej „Europa/Londyn”. Obydwa datetime
s wydrukuje różne wartości, używając przesunięcia UTC jako łącza odniesienia między nimi:
America/New_York: 2022-11-30 21:24:30.123400-05:00
Europe/London: 2022-12-01 02:24:30.123400+00:00
2:24 następnego dnia w Londynie is ten sam punkt w czasie, co 21:24 poprzedniego dnia w Nowym Jorku ponieważ Londyn jest 5 godzin do przodu.
Zgodnie z oczekiwaniami daty i godziny są różne, ponieważ dzieli je około 5 godzin.
Konwertuj ciąg znaków na datę i godzinę przy użyciu bibliotek stron trzecich
Pythona datetime
moduł może konwertować wszystkie różne typy ciągów znaków do formatu datetime
obiekt. Ale głównym problemem jest to, że aby to zrobić, musisz utworzyć odpowiedni ciąg kodu formatowania strptime()
móc zrozumieć. Utworzenie tego ciągu zajmuje trochę czasu i utrudnia odczytanie kodu.
Zamiast tego możemy użyć innych bibliotek innych firm, aby to ułatwić.
W niektórych przypadkach te biblioteki innych firm mają również lepszą wbudowaną obsługę manipulowania i porównywania dat i godzin, a niektóre mają nawet wbudowane strefy czasowe, więc nie trzeba dołączać dodatkowego pakietu PyTz.
Przyjrzyjmy się kilku z tych bibliotek w poniższych sekcjach.
Konwertuj ciąg na Datetime za pomocą dateutil
Połączenia moduł dateutil jest rozszerzeniem do datetime
moduł. Jedną z zalet jest to, że nie musimy przekazywać żadnego kodu analizującego, aby przeanalizować ciąg znaków!
Aby automatycznie przekonwertować ciąg na datetime bez tokena formatu przy użyciu języka Python dateutil
:
from dateutil.parser import parse
datetime = parse('2018-06-29 22:21:41')
print(datetime)
To zdjęcie parse
funkcja automatycznie przeanalizuje ciąg znaków! Nie musisz dołączać żadnego ciągu formatującego. Spróbujmy przeanalizować różne typy łańcuchów przy użyciu dateutil
:
from dateutil.parser import parse
date_array = [
'2018-06-29 08:15:27.243860',
'Jun 28 2018 7:40AM',
'Jun 28 2018 at 7:40AM',
'September 18, 2017, 22:19:55',
'Sun, 05/12/1999, 12:30PM',
'Mon, 21 March, 2015',
'2018-03-12T10:12:45Z',
'2018-06-29 17:08:00.586525+00:00',
'2018-06-29 17:08:00.586525+05:00',
'Tuesday , 6th September, 2017 at 4:30pm'
]
for date in date_array:
print('Parsing: ' + date)
dt = parse(date)
print(dt.date())
print(dt.time())
print(dt.tzinfo)
print('n')
Wyjście:
Parsing: 2018-06-29 08:15:27.243860
2018-06-29
08:15:27.243860
None
Parsing: Jun 28 2018 7:40AM
2018-06-28
07:40:00
None
Parsing: Jun 28 2018 at 7:40AM
2018-06-28
07:40:00
None
Parsing: September 18, 2017, 22:19:55
2017-09-18
22:19:55
None
Parsing: Sun, 05/12/1999, 12:30PM
1999-05-12
12:30:00
None
Parsing: Mon, 21 March, 2015
2015-03-21
00:00:00
None
Parsing: 2018-03-12T10:12:45Z
2018-03-12
10:12:45
tzutc()
Parsing: 2018-06-29 17:08:00.586525+00:00
2018-06-29
17:08:00.586525
tzutc()
Parsing: 2018-06-29 17:08:00.586525+05:00
2018-06-29
17:08:00.586525
tzoffset(None, 18000)
Parsing: Tuesday , 6th September, 2017 at 4:30pm
2017-09-06
16:30:00
None
Jak widać, prawie każdy typ łańcucha można łatwo przeanalizować za pomocą metody dateutil
moduł.
Chociaż jest to wygodne, pamiętaj, że przewidywanie formatu znacznie spowalnia kod, więc jeśli kod wymaga wysokiej wydajności, może to nie być właściwe podejście do Twojej aplikacji.
Konwertuj ciąg znaków na datę i godzinę za pomocą programu Maya
Maya sprawia również, że bardzo łatwo jest analizować łańcuch i zmieniać strefy czasowe. Aby łatwo przekonwertować ciąg znaków za pomocą Pythona Maya:
import maya
dt = maya.parse('2018-04-29T17:45:25Z').datetime()
print(dt.date())
print(dt.time())
print(dt.tzinfo)
Wyjście:
2018-04-29
17:45:25
UTC
Aby przekonwertować czas na inną strefę czasową:
import maya
dt = maya.parse('2018-04-29T17:45:25Z').datetime(to_timezone='America/New_York', naive=False)
print(dt.date())
print(dt.time())
print(dt.tzinfo)
Wyjście:
2018-04-29
13:45:25
America/New_York
Czy to nie jest łatwe w użyciu? spróbujmy maya
z tym samym zestawem strun, z którym korzystaliśmy dateutil
:
import maya
date_array = [
'2018-06-29 08:15:27.243860',
'Jun 28 2018 7:40AM',
'Jun 28 2018 at 7:40AM',
'September 18, 2017, 22:19:55',
'Sun, 05/12/1999, 12:30PM',
'Mon, 21 March, 2015',
'2018-03-12T10:12:45Z',
'2018-06-29 17:08:00.586525+00:00',
'2018-06-29 17:08:00.586525+05:00',
'Tuesday , 6th September, 2017 at 4:30pm'
]
for date in date_array:
print('Parsing: ' + date)
dt = maya.parse(date).datetime()
print(dt)
Wyjście:
Parsing: 2018-06-29 08:15:27.243860
2018-06-29 08:15:27.243860+00:00
Parsing: Jun 28 2018 7:40AM
2018-06-28 07:40:00+00:00
Parsing: Jun 28 2018 at 7:40AM
2018-06-28 07:40:00+00:00
Parsing: September 18, 2017, 22:19:55
2017-09-18 22:19:55+00:00
Parsing: Sun, 05/12/1999, 12:30PM
1999-05-12 12:30:00+00:00
Parsing: Mon, 21 March, 2015
2015-03-21 00:00:00+00:00
Parsing: 2018-03-12T10:12:45Z
2018-03-12 10:12:45+00:00
Parsing: 2018-06-29 17:08:00.586525+00:00
2018-06-29 17:08:00.586525+00:00
Parsing: 2018-06-29 17:08:00.586525+05:00
2018-06-29 12:08:00.586525+00:00
Parsing: Tuesday , 6th September, 2017 at 4:30pm
2017-09-06 16:30:00+00:00
Jak widać, wszystkie formaty dat zostały pomyślnie przeanalizowane!
Jeśli nie podamy informacji o strefie czasowej, automatycznie przekonwertuje ją na UTC. Warto więc zauważyć, że my musi zapewnić to_timezone
i naive
parametry, jeśli czas nie jest w formacie UTC.
Konwertuj ciąg znaków na datę i godzinę za pomocą strzałki
Strzałka to kolejna biblioteka do obsługi datetime w Pythonie. I jak poprzednio z maya
, automatycznie określa również format daty i godziny. Po zinterpretowaniu zwraca Pythona datetime
obiekt z arrow
obiekt.
Aby łatwo przekonwertować ciąg na datetime za pomocą Pythona arrow
:
import arrow
dt = arrow.get('2018-04-29T17:45:25Z')
print(dt.date())
print(dt.time())
print(dt.tzinfo)
Wyjście:
2018-04-29
17:45:25
tzutc()
A oto jak możesz użyć arrow
do konwersji stref czasowych za pomocą to()
metoda:
import arrow
dt = arrow.get('2018-04-29T17:45:25Z').to('America/New_York')
print(dt)
print(dt.date())
print(dt.time())
Wyjście:
2018-04-29T13:45:25-04:00
2018-04-29
13:45:25
Jak widać ciąg daty i godziny jest konwertowany na region „America/New_York”.
Teraz ponownie użyjmy tego samego zestawu ciągów znaków, którego użyliśmy powyżej:
import arrow
date_array = [
'2018-06-29 08:15:27.243860',
'2018-03-12T10:12:45Z',
'2018-06-29 17:08:00.586525+00:00',
'2018-06-29 17:08:00.586525+05:00',
]
for date in date_array:
dt = arrow.get(date)
print('Parsing: ' + date)
print(dt)
Ten kod zakończy się niepowodzeniem dla ciągów daty i godziny, które zostały wykomentowane, co stanowi ponad połowę naszych przykładów. Dane wyjściowe dla innych ciągów będą następujące:
Parsing: 2018-06-29 08:15:27.243860
2018-06-29T08:15:27.243860+00:00
Parsing: 2018-03-12T10:12:45Z
2018-03-12T10:12:45+00:00
Parsing: 2018-06-29 17:08:00.586525+00:00
2018-06-29T17:08:00.586525+00:00
Parsing: 2018-06-29 17:08:00.586525+05:00
2018-06-29T17:08:00.586525+05:00
Aby poprawnie przeanalizować ciągi daty i godziny, które są skomentowane, musisz przekazać odpowiednie formatować tokeny dać bibliotekom wskazówki, jak je analizować.
Wnioski
W tym artykule pokazaliśmy różne sposoby parsowania łańcucha na a datetime
obiekt w Pythonie. Możesz wybrać domyślny Python datetime
biblioteka lub dowolna z bibliotek stron trzecich wymienionych w tym artykule, wśród wielu innych.
Główny problem z domyślnym datetime
pakiet polega na tym, że musimy ręcznie określić kod parsowania dla prawie wszystkich formatów ciągów daty i godziny. Tak więc, jeśli format łańcucha zmieni się w przyszłości, prawdopodobnie będziesz musiał również zmienić swój kod. Ale wiele bibliotek innych firm, takich jak te wymienione tutaj, obsługuje to automatycznie.
Jeszcze jeden problem, przed którym stoimy, dotyczy stref czasowych. Najlepszym sposobem radzenia sobie z nimi jest zawsze przechowywanie czasu w bazie danych w formacie UTC, a następnie w razie potrzeby przekonwertowanie go na lokalną strefę czasową użytkownika.
Biblioteki te są nie tylko dobre do analizowania ciągów znaków, ale mogą być używane do wielu różnych typów operacji związanych z datą i godziną. Zachęcam do przejrzenia dokumentów w celu szczegółowego poznania funkcjonalności.