Introducere
Datele pot fi reprezentate în diferite forme – și un mod convenabil de a reprezenta datele și orele sunt siruri. Cu toate acestea, pentru a lucra cu aceste date și ore într-un mod aritmetic (cum ar fi calcularea diferențelor de timp, adăugarea sau eliminarea timpului etc.) - trebuie să le convertim într-un datetime
obiect.
Una dintre cele mai comune surse de date și ore formatate în șir sunt API-uri REST care returnează șiruri agnostice, pe care apoi le putem converti în alte formate.
În plus, fusurile orare sunt o durere de cap obișnuită atunci când vine vorba de lucrul cu obiecte datetime, așa că va trebui să ne gândim și la asta în timpul conversiei.
În acest ghid, vom arunca o privire la cum să convertim un șir de date/ora în a
datetime
obiect în Python, folosind încorporatdatetime
modul, dar și module terțe precumdateutil
,arrow
și Maya, ținând cont de fusurile orare.
Conversia șirurilor de caractere folosind datetime
datetime modulul constă din trei tipuri diferite de obiecte: date
, time
, și datetime
. date
obiectul deține data, time
ține timpul și datetime
păstrează atât data, cât și ora!
import datetime
print(f'Current date/time: {datetime.datetime.now()}')
Rularea acestui cod ar avea ca rezultat:
Current date/time: 2022-12-01 10:27:03.929149
Când nu se oferă nicio formatare personalizată, este utilizat formatul implicit de șir, adică formatul pentru „2022-12-01 10:27:03.929149” este în ISO 8601 format (AAAA-LL-ZZA:LL:SS.mmmmmm). Dacă șirul nostru de intrare pentru a crea un datetime
obiectul este în același format ISO 8601 sau dacă cunoașteți formatul pe care îl veți primi în avans, îl putem analiza cu ușurință într-un datetime
obiect:
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)
Rularea acestuia va imprima data, ora și data-ora:
Date: 2022-12-01
Time: 10:27:03.929149
Date-time: 2022-12-01 10:27:03.929149
Aici, folosim strptime()
metoda, care acceptă două argumente:
- Data formatată în șir
- Formatul primului argument
Specificarea formatului astfel face analizarea mult mai rapidă de atunci datetime
nu trebuie să încerce să interpreteze formatul singur, ceea ce este mult mai costisitor din punct de vedere computațional. Valoarea returnată este de tipul datetime
.
În exemplul nostru, "2022-12-01 10:27:03.929149"
este șirul de intrare și "%Y-%m-%d %H:%M:%S.%f"
este formatul șirului nostru de date. Cei întors datetime
valoarea este stocată ca date_time_obj
.
Deoarece acesta este un datetime
obiect, putem numi date()
și time()
metode direct pe ea. După cum puteți vedea din rezultat, imprimă partea „data” și „ora” a șirului de intrare!
Formatați jetoane
Merită să luați un moment pentru a înțelege jetoane de format - "%Y-%m-%d %H:%M:%S.%f"
dinainte.
Fiecare simbol reprezintă o parte diferită a datei-ora, cum ar fi ziua, luna, anul, ziua lunii sau a săptămânii etc. lista de jetoane acceptate este suficient de extins pentru a permite diverse formatări. Unele dintre cele utilizate în mod obișnuit, pe care le-am folosit și mai devreme sunt:
%Y
: An (4 cifre)%m
: Luna%d
: Ziua lunii%H
: oră (24 de ore)%M
: Minute%S
: Secunde%f
: Microsecunde
Notă: Toate aceste jetoane, cu excepția anului, sunt de așteptat să fie cu zero (adică august este a 8-a lună și este cu zero pentru 08
).
Utilizarea jetoanelor de format strptime() pentru a converti șirul într-un format de dată și oră diferit
Dacă formatul unui șir este cunoscut, acesta poate fi ușor analizat la a datetime
obiect folosind strptime()
. Să aruncăm o privire la un exemplu non-trivial care se traduce dintr-un format în altul:
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)
Șirul de intrare avea un singur format – „17 iulie 2022 9:20”. Cunoscând acest format, am mapat elementele constitutive la formatul ISO 8601 și l-am convertit într-un datetime
obiect:
Date: 2022-07-17
Time: 09:20:00
Date-time: 2022-07-17 09:20:00
Iată o listă scurtă de date obișnuite formatate în șir și formatele corespunzătoare pentru 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"
Puteți analiza un șir dată-oră de orice format – atâta timp cât utilizați șirul corect de simboluri de format pentru intrarea pe care o primiți.
Convertiți șirul în date și oră cu fusuri orare
Gestionarea date-orelor devine mai complexă în timp ce vă ocupați de fusurile orare. Toate exemplele de mai sus de până acum sunt naive față de fusul orar. Acestea sunt cunoscute ca obiecte datetime naive.
Cu toate acestea, datetime
obiectele conțin un câmp exact pentru stocarea datelor legate de fusul orar – tzinfo
:
import datetime as dt
dtime = dt.datetime.now()
print(dtime)
print(dtime.tzinfo)
tzinfo
câmpul este menit să fie a datetime.timezone
obiect, indicând informațiile despre fusul orar. este None
implicit și indică faptul că obiectul datetime este naiv pentru fusul orar. O bibliotecă externă foarte comună pentru gestionarea fusurilor orare este pytz
. Puteți seta PyTz obiecte ca tzinfo
câmpul de asemenea.
Dacă nu îl aveți deja - instalați-l prin:
$ pip install pytz
Folosind PyTz, putem crea o ancoră pentru date care țin cont de fusul orar, cum ar fi UTC:
import datetime as dt
import pytz
dtime = dt.datetime.now(pytz.utc)
print(dtime)
print(dtime.tzinfo)
ieșire:
2022-12-01 02:07:41.960920+00:00
UTC
Nu mai este 11:2, ci XNUMX:XNUMX, pentru că am setat fusul orar cu câteva ore în urmă! Acest schimbă fusul orar a datei ora.
+00:00
este diferența dintre ora afișată și ora UTC ca ancoră de coordonare globală. Am setat ora să fie în UTC, deci decalajul este 00:00
. Aceasta este o obiect care știe fusul orar.
În mod similar, putem schimba interpretarea aceleiași date și ore între fusurile orare. Să convertim un șir, cum ar fi „2022-06-29 17:08:00” într-o dată și apoi localiza la fusul orar „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)
Notă: Localizare transformă o dată-oră naiv pentru fusul orar într-o dată-oră care ține cont de fusul orar și tratează fusul orar ca pe cel local. Astfel, cel data ora rămâne aceeași, dar având în vedere fusul orar diferit, acesta nu mai reprezintă același moment în timp nelegat de fusul orar.
Primim la fel valoarea datetime, compensat cu -04: 00 comparativ cu ora UTC:
2022-06-29 17:08:00-04:00
America/New_York
17:08 la Tokyo nu este același punct în timp ca 17:08 în New York. 17:08 în Tokyo este 3:08 în New York.
Cum să găsiți toate codurile/alias-urile fusului orar?
Pentru a găsi toate fusurile orare disponibile, inspectați all_timezones
câmp, care este o listă cu toate fusurile orare disponibile:
print(f'There are {len(pytz.all_timezones)} timezones in PyTzn')
for time_zone in pytz.all_timezones:
print(time_zone)
Consultați ghidul nostru practic și practic pentru a învăța Git, cu cele mai bune practici, standarde acceptate de industrie și fisa de cheat incluse. Opriți căutarea pe Google a comenzilor Git și de fapt învăţa aceasta!
There are 594 timezones in PyTz
Africa/Abidjan
Africa/Accra
Africa/Addis_Ababa
Africa/Algiers
Africa/Asmara
Africa/Asmera
...
Schimbați fusul orar al datei și orei
Putem converti fusul orar al unui fus orar conștient datetime
obiect dintr-o regiune în alta, în loc de a localiza un fus orar naiv datetime prin prisma unui fus orar.
Acest lucru este diferit de localizare, deoarece localizarea reprezintă un moment diferit în timp, dar conversia fusului orar al unui obiect reprezintă același moment în timp, printr-o lentilă diferită:
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)
Mai întâi, am creat un obiect datetime cu ora curentă și l-am setat ca fus orar „America/New_York”. Apoi, folosind astimezone()
metoda, am convertit aceasta datetime
la fusul orar „Europa/Londra”. Ambii datetime
s va imprima valori diferite, folosind offset-ul UTC ca legătură de referință între ele:
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 a doua zi la Londra is același moment ca ora 21:24 din ziua precedentă la New York deoarece Londra este cu 5h înainte.
După cum era de așteptat, datele și orele sunt diferite, deoarece sunt la aproximativ 5 ore între ele.
Convertiți șirul în date și oră folosind biblioteci terțe
Python's datetime
modulul poate converti toate tipurile diferite de șiruri în a datetime
obiect. Dar principala problemă este că, pentru a face acest lucru, trebuie să creați șirul de cod de formatare adecvat care strptime()
pot intelege. Crearea acestui șir necesită timp și face codul mai greu de citit.
În schimb, putem folosi alte biblioteci terțe pentru a face acest lucru mai ușor.
În unele cazuri, aceste biblioteci terță parte au, de asemenea, un suport încorporat mai bun pentru manipularea și compararea date-orelor, iar unele au chiar și fusuri orare încorporate, deci nu trebuie să includeți un pachet PyTz suplimentar.
Să aruncăm o privire la câteva dintre aceste biblioteci în secțiunile următoare.
Convertiți String în Datetime cu dateutil
module dateutil este o extensie a datetime
modul. Un avantaj este că nu trebuie să transmitem niciun cod de analiză pentru a analiza un șir!
Pentru a converti automat un șir în datetime fără un token de format folosind Python dateutil
:
from dateutil.parser import parse
datetime = parse('2018-06-29 22:21:41')
print(datetime)
Acest parse
funcția va analiza automat șirul! Nu trebuie să includeți niciun șir de format. Să încercăm să analizăm diferite tipuri de șiruri folosind 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')
ieșire:
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
Puteți vedea că aproape orice tip de șir poate fi analizat cu ușurință folosind dateutil
modul.
Deși acest lucru este convenabil, amintiți-vă de mai devreme că faptul că trebuie să preziceți formatul face ca codul să fie mult mai lent, așa că dacă codul dvs. necesită performanțe ridicate, aceasta ar putea să nu fie abordarea potrivită pentru aplicația dvs.
Convertiți String în Datetime cu Maya
maya de asemenea, face foarte ușor să analizați un șir și să schimbați fusurile orare. Pentru a converti cu ușurință un șir cu Maya lui Python:
import maya
dt = maya.parse('2018-04-29T17:45:25Z').datetime()
print(dt.date())
print(dt.time())
print(dt.tzinfo)
ieșire:
2018-04-29
17:45:25
UTC
Pentru a converti ora într-un alt fus orar:
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)
ieșire:
2018-04-29
13:45:25
America/New_York
Acum nu este atât de ușor de folosit? Să încercăm maya
cu același set de șiruri cu care am folosit 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)
ieșire:
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
După cum puteți vedea, toate formatele de date au fost analizate cu succes!
Dacă nu furnizăm informațiile despre fusul orar, atunci le convertește automat în UTC. Deci, este important să rețineți că noi trebuie sa asigurarea to_timezone
și naive
parametri dacă ora nu este în UTC.
Convertiți șirul în date și oră cu săgeata
Săgeată este o altă bibliotecă pentru a se ocupa de data și ora în Python. Și ca înainte cu maya
, de asemenea, descoperă automat formatul de dată și oră. Odată interpretat, returnează un Python datetime
obiect din arrow
obiect.
Pentru a converti cu ușurință un șir în datetime folosind Python arrow
:
import arrow
dt = arrow.get('2018-04-29T17:45:25Z')
print(dt.date())
print(dt.time())
print(dt.tzinfo)
ieșire:
2018-04-29
17:45:25
tzutc()
Și iată cum poți folosi arrow
pentru a converti fusurile orare folosind to()
metodă:
import arrow
dt = arrow.get('2018-04-29T17:45:25Z').to('America/New_York')
print(dt)
print(dt.date())
print(dt.time())
ieșire:
2018-04-29T13:45:25-04:00
2018-04-29
13:45:25
După cum puteți vedea, șirul dată-oră este convertit în regiunea „America/New_York”.
Acum, să folosim din nou același set de șiruri pe care l-am folosit mai sus:
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)
Acest cod va eșua pentru șirurile de dată-oră care au fost comentate, ceea ce reprezintă peste jumătate din exemplele noastre. Ieșirea pentru alte șiruri va fi:
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
Pentru a analiza corect șirurile de dată-oră care sunt comentate, va trebui să treceți jetoane de format pentru a oferi bibliotecii indicii despre cum să o analizeze.
Concluzie
În acest articol am arătat diferite moduri de a analiza un șir în a datetime
obiect în Python. Puteți opta fie pentru Python implicit datetime
bibliotecă sau oricare dintre bibliotecile terțe menționate în acest articol, printre multe altele.
Principala problemă cu implicit datetime
pachetul este că trebuie să specificăm manual codul de analiză pentru aproape toate formatele de șir de date și oră. Deci, dacă formatul șirului dvs. de caractere se schimbă în viitor, probabil că va trebui să vă schimbați și codul. Dar multe biblioteci terțe, precum cele menționate aici, se ocupă automat.
Încă o problemă cu care ne confruntăm este să ne ocupăm de fusurile orare. Cel mai bun mod de a le gestiona este întotdeauna să stocați ora în baza de date în format UTC și apoi să o convertiți în fusul orar local al utilizatorului atunci când este necesar.
Aceste biblioteci nu sunt bune numai pentru analizarea șirurilor de caractere, dar pot fi folosite pentru o mulțime de tipuri diferite de operațiuni legate de dată și oră. Vă încurajez să parcurgeți documentele pentru a afla funcționalitățile în detaliu.