Pretvarjanje nizov v datum in čas v Pythonu

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 vgrajenega datetime modul, ampak tudi moduli tretjih oseb, kot je npr dateutil, 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, timein 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 datetimes 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.

Časovni žig:

Več od Stackabuse