Predstavitev
Podatke je mogoče predstaviti v različnih oblikah – in priročen način za predstavitev datumov in ur sta strune. Če želimo delati s temi datumi in časi na aritmetični način (kot je izračunavanje časovnih razlik, dodajanje ali odstranjevanje časa itd.), jih moramo pretvoriti v datetime
predmet.
Eden najpogostejših virov datumski časi v obliki niza so REST API-ji, ki vrnejo agnostične nize, ki jih lahko nato pretvorimo v druge formate.
Poleg tega – časovni pasovi so pogost glavobol, ko gre za delo s predmeti datuma in časa, zato bomo morali med pretvorbo razmišljati tudi o tem.
V tem priročniku si bomo ogledali, kako pretvoriti datum/čas niza v a
datetime
objekt v Pythonu z uporabo vgrajenegadatetime
modul, ampak tudi moduli tretjih oseb, kot je nprdateutil
,arrow
in Maya, ki upošteva časovne pasove.
Pretvarjanje nizov z uporabo datuma in časa
O Datum čas modul je sestavljen iz treh različnih tipov objektov: date
, time
in datetime
. date
predmet ima datum, time
drži čas in datetime
ima tako datum kot uro!
import datetime
print(f'Current date/time: {datetime.datetime.now()}')
Če uporabite to kodo, bi prišlo do:
Current date/time: 2022-12-01 10:27:03.929149
Če oblikovanje po meri ni podano, se uporabi privzeta oblika niza, tj. oblika za »2022-12-01 10:27:03.929149« je v ISO 8601 format (LLLL-MM-DDTHH:MM:SS.mmmmmm). Če naš vhodni niz ustvari a datetime
je predmet v istem formatu ISO 8601 ali če poznate format, ki ga boste prejeli vnaprej, ga lahko preprosto razčlenimo na datetime
predmet:
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)
Če ga zaženete, se bodo natisnili datum, čas in datum-čas:
Date: 2022-12-01
Time: 10:27:03.929149
Date-time: 2022-12-01 10:27:03.929149
Tu uporabljamo strptime()
metoda, ki sprejme dva argumenta:
- Datum v obliki niza
- Oblika prvega argumenta
Če tako določite format, je razčlenjevanje veliko hitrejše datetime
formata ni treba poskušati interpretirati sam, kar je računsko veliko dražje. Vrnjena vrednost je tipa datetime
.
V našem primeru "2022-12-01 10:27:03.929149"
je vhodni niz in "%Y-%m-%d %H:%M:%S.%f"
je oblika našega datumskega niza. Vrnilo se je datetime
vrednost je shranjena kot date_time_obj
.
Ker je to a datetime
predmet, lahko imenujemo date()
in time()
metode neposredno na njej. Kot lahko vidite iz izhoda, natisne del 'datum' in 'čas' vhodnega niza!
Oblikujte žetone
Vredno si je vzeti trenutek, da razumemo format žetonov - za "%Y-%m-%d %H:%M:%S.%f"
od prej.
Vsak žeton predstavlja drugačen del datuma-časa, na primer dan, mesec, leto, dan v mesecu ali teden itd. seznam podprtih žetonov je dovolj obsežen, da omogoča različno oblikovanje. Nekaj pogosto uporabljenih, ki smo jih uporabljali tudi prej, je:
%Y
: leto (4 števke)%m
: Mesec%d
: Dan v mesecu%H
: ura (24 ur)%M
: Minute%S
: sekund%f
: mikrosekunde
Opomba: Vsi ti žetoni, razen leta, naj bi bili podloženi z ničlami (tj. avgust je 8. mesec in je podložen z ničlami do 08
).
Uporaba žetonov oblikovanja strptime() za pretvorbo niza v drugo obliko datuma in časa
Če je format niza znan, ga je mogoče zlahka razčleniti na a datetime
uporabo predmeta strptime()
. Oglejmo si netrivialen primer, ki prevaja iz ene oblike v drugo:
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)
Vnosni niz je bil v eni obliki – »17. julij 2022 9:20«. Ker smo poznali ta format, smo sestavne elemente preslikali v format ISO 8601 in ga pretvorili v datetime
predmet:
Date: 2022-07-17
Time: 09:20:00
Date-time: 2022-07-17 09:20:00
Tukaj je kratek seznam pogostih datumskih časov v obliki niza in njihovih ustreznih formatov za 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"
Niz datuma in časa lahko razčlenite v kateri koli obliki – če uporabljate pravilen niz žetonov oblike za vnos, ki ga prejemate.
Pretvori niz v datum in čas s časovnimi pasovi
Ravnanje z datumi in časi postane bolj zapleteno, ko se ukvarjate s časovnimi pasovi. Vsi zgornji primeri do sedaj so naivni za časovni pas. Ti so znani kot naivni predmeti datum-čas.
Vendar datetime
objekti vsebujejo polje točno za shranjevanje podatkov, povezanih s časovnim pasom – tzinfo
:
import datetime as dt
dtime = dt.datetime.now()
print(dtime)
print(dtime.tzinfo)
O tzinfo
polje naj bi bilo a datetime.timezone
predmet, ki označuje informacije o časovnem pasu. je None
privzeto in označuje, da objekt datetime ne uporablja časovnega pasu. Zelo pogosta zunanja knjižnica za upravljanje časovnih pasov je pytz
. Lahko nastavite PyTz predmetov kot tzinfo
polje tudi.
Če ga še nimate – namestite ga preko:
$ pip install pytz
Z uporabo PyTz lahko ustvarimo sidro za datume, ki poznajo časovni pas, kot je UTC:
import datetime as dt
import pytz
dtime = dt.datetime.now(pytz.utc)
print(dtime)
print(dtime.tzinfo)
izhod:
2022-12-01 02:07:41.960920+00:00
UTC
Ni več 11 zjutraj, ampak 2 zjutraj, ker smo časovni pas nastavili nekaj ur nazaj! to spremeni časovni pas datuma in ure.
+00:00
je razlika med prikazanim časom in časom UTC kot globalnim koordinacijskim sidrom. Nastavili smo čas v UTC, tako da je odmik enak 00:00
. Gre objekt, ki pozna časovni pas.
Podobno lahko preklapljamo isto interpretacijo datuma in časa med časovnimi pasovi. Pretvorimo niz, kot je »2022-06-29 17:08:00« v datum in uro in nato lokalizirati na časovni pas »Amerika/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)
Opomba: Lokalizacija spremeni časovno-naivni datum-čas v datum-čas, ki pozna časovni pas, in obravnava časovni pas kot lokalni. Tako je datum in čas ostane enak, vendar glede na drug časovni pas ne predstavlja več iste časovne točke, nevezane na časovne pasove.
Enako dobimo vrednost datuma in časa, izravnano z -04: 00 v primerjavi s časom UTC:
2022-06-29 17:08:00-04:00
America/New_York
17:08 v Tokiu ni isto kot ob 17:08 v New Yorku. 17:08 v Tokiu je 3:08 v New Yorku.
Kako najti vse kode/vzdevke časovnih pasov?
Če želite najti vse razpoložljive časovne pasove, preglejte all_timezones
polje, ki je seznam vseh razpoložljivih časovnih pasov:
print(f'There are {len(pytz.all_timezones)} timezones in PyTzn')
for time_zone in pytz.all_timezones:
print(time_zone)
Oglejte si naš praktični, praktični vodnik za učenje Gita z najboljšimi praksami, standardi, sprejetimi v panogi, in priloženo goljufijo. Nehajte Googlati ukaze Git in pravzaprav naučiti it!
There are 594 timezones in PyTz
Africa/Abidjan
Africa/Accra
Africa/Addis_Ababa
Africa/Algiers
Africa/Asmara
Africa/Asmera
...
Spremenite časovni pas Datetime
Časovni pas lahko pretvorimo v časovni pas datetime
predmeta iz ene regije v drugo, namesto da bi lokalizirali datum in čas, ki je naiven glede na časovni pas, skozi lečo nekega časovnega pasu.
To se razlikuje od lokalizacije, saj lokalizacija predstavlja drugo časovno točko, vendar pretvorba časovnega pasu predmeta predstavlja isto časovno točko skozi drugačno lečo:
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)
Najprej smo ustvarili en objekt datetime s trenutnim časom in ga nastavili kot časovni pas »America/New_York«. Nato z uporabo astimezone()
metodo, smo to pretvorili datetime
na časovni pas "Evropa/London". Oboje datetime
s bo natisnil različne vrednosti z uporabo odmika UTC kot referenčne povezave med njimi:
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 naslednji dan v Londonu is isti čas kot 21:24 prejšnji dan v New Yorku saj je London 5h naprej.
Kot je bilo pričakovano, sta datuma in časa drugačna, saj sta približno 5 ur narazen.
Pretvorite niz v datum in čas z uporabo knjižnic tretjih oseb
Pythonova datetime
modul lahko pretvori vse različne vrste nizov v a datetime
predmet. Toda glavna težava je, da morate za to ustvariti ustrezen niz kode za oblikovanje, ki strptime()
lahko razume. Ustvarjanje tega niza zahteva čas in kodo je težje brati.
Namesto tega lahko za lažjo uporabo uporabimo druge knjižnice tretjih oseb.
V nekaterih primerih imajo te knjižnice tretjih oseb tudi boljšo vgrajeno podporo za manipulacijo in primerjavo datumov in ur, nekatere pa imajo celo vgrajene časovne pasove, tako da vam ni treba vključiti dodatnega paketa PyTz.
Oglejmo si nekaj teh knjižnic v naslednjih razdelkih.
Pretvorite niz v datum in čas z dateutil
O modul dateutil je razširitev na datetime
modul. Ena od prednosti je, da nam za razčlenjevanje niza ni treba posredovati nobene kode za razčlenjevanje!
Za samodejno pretvorbo niza v datum in čas brez žetona formata z uporabo Pythona dateutil
:
from dateutil.parser import parse
datetime = parse('2018-06-29 22:21:41')
print(datetime)
Ta parse
funkcija bo samodejno razčlenila niz! Ni vam treba vključiti nobenega formatnega niza. Poskusimo razčleniti različne vrste nizov z uporabo 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')
izhod:
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
Vidite lahko, da je skoraj vsako vrsto niza mogoče enostavno razčleniti z uporabo dateutil
modul.
Čeprav je to priročno, se spomnite od prej, da je zaradi predvidevanja formata koda veliko počasnejša, tako da, če vaša koda zahteva visoko zmogljivost, to morda ni pravi pristop za vašo aplikacijo.
Pretvorite niz v datum in uro z Mayo
Maya omogoča tudi zelo enostavno razčlenjevanje niza in spreminjanje časovnih pasov. Za preprosto pretvorbo niza s Pythonovo Mayo:
import maya
dt = maya.parse('2018-04-29T17:45:25Z').datetime()
print(dt.date())
print(dt.time())
print(dt.tzinfo)
izhod:
2018-04-29
17:45:25
UTC
Za pretvorbo časa v drug časovni pas:
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)
izhod:
2018-04-29
13:45:25
America/New_York
Ali ni tako enostavno uporabljati? Poskusimo maya
z istim naborom nizov, kot smo jih uporabili 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)
izhod:
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
Kot lahko vidite, so bili vsi formati datumov uspešno razčlenjeni!
Če takrat ne zagotovimo informacij o časovnem pasu, jih samodejno pretvori v UTC. Zato je pomembno opozoriti, da mi morajo zagotoviti to_timezone
in naive
parametrov, če čas ni v UTC.
Pretvori niz v datum in uro s puščico
arrow je še ena knjižnica za obravnavo datuma in časa v Pythonu. In kot prej z maya
, samodejno ugotovi tudi obliko datuma in časa. Po interpretaciji vrne Python datetime
predmet iz arrow
predmet.
Za preprosto pretvorbo niza v datum in čas z uporabo Pythona arrow
:
import arrow
dt = arrow.get('2018-04-29T17:45:25Z')
print(dt.date())
print(dt.time())
print(dt.tzinfo)
izhod:
2018-04-29
17:45:25
tzutc()
In tukaj je, kako lahko uporabite arrow
za pretvorbo časovnih pasov z uporabo to()
metoda:
import arrow
dt = arrow.get('2018-04-29T17:45:25Z').to('America/New_York')
print(dt)
print(dt.date())
print(dt.time())
izhod:
2018-04-29T13:45:25-04:00
2018-04-29
13:45:25
Kot lahko vidite, je niz datuma in časa pretvorjen v regijo »America/New_York«.
Zdaj pa spet uporabimo isti nabor nizov, kot smo jih uporabili zgoraj:
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)
Ta koda ne bo delovala za nize datuma in časa, ki so bili komentirani, kar je več kot polovica naših primerov. Izhod za druge nize bo:
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
Če želite pravilno razčleniti datumsko-časovne nize, ki so komentirani, boste morali posredovati ustrezen format žetonov da bi knjižnici dali namige, kako ga razčleniti.
zaključek
V tem članku smo prikazali različne načine za razčlenitev niza na a datetime
objekt v Pythonu. Lahko se odločite za privzeti Python datetime
knjižnico ali katero koli drugo knjižnico, omenjeno v tem članku, med mnogimi drugimi.
Glavna težava privzeto datetime
paket je, da moramo kodo za razčlenjevanje določiti ročno za skoraj vse formate datumsko-časovnih nizov. Torej, če se bo vaš format niza v prihodnosti spremenil, boste verjetno morali spremeniti tudi kodo. Toda številne knjižnice drugih proizvajalcev, kot so tukaj omenjene, to obravnavajo samodejno.
Še en problem, s katerim se soočamo, je ukvarjanje s časovnimi pasovi. Najboljši način za njihovo obravnavo je vedno shranjevanje časa v vaši zbirki podatkov v formatu UTC in nato po potrebi pretvorba v uporabnikov lokalni časovni pas.
Te knjižnice niso dobre le za razčlenjevanje nizov, ampak jih je mogoče uporabiti za veliko različnih vrst operacij, povezanih z datumom in uro. Spodbujam vas, da pregledate dokumente, da se podrobno seznanite s funkcijami.