Introduksjon
Data kan representeres i ulike former - og en praktisk måte å representere datoer og klokkeslett er strenger. Men for å arbeide med disse datoene og tidspunktene på en aritmetisk måte (som å beregne tidsforskjeller, legge til eller fjerne tid osv.) – må vi konvertere dem til en datetime
gjenstand.
En av de vanligste kildene til strengformaterte datotider er REST APIer som returnerer agnostiske strenger, som vi så kan konvertere til andre formater.
I tillegg – tidssoner er en vanlig hodepine når det gjelder å jobbe med datetime-objekter, så vi må tenke på det mens vi konverterer også.
I denne veiledningen – vi tar en titt på hvordan du konverterer en strengdato/-klokkeslett til en
datetime
objekt i Python, ved å bruke den innebygdedatetime
modul, men også tredjepartsmoduler som f.eksdateutil
,arrow
og Maya, som står for tidssoner.
Konvertering av strenger ved hjelp av datetime
De dato tid Modulen består av tre forskjellige objekttyper: date
, time
og datetime
. De date
objektet inneholder datoen, time
holder tiden, og datetime
holder både dato og klokkeslett!
import datetime
print(f'Current date/time: {datetime.datetime.now()}')
Å kjøre denne koden vil resultere i:
Current date/time: 2022-12-01 10:27:03.929149
Når ingen egendefinert formatering er gitt, brukes standard strengformat, dvs. formatet for "2022-12-01 10:27:03.929149" er i ISO 8601 format (ÅÅÅÅ-MM-DDTHH:MM:SS.mmmmmm). Hvis vår inndatastreng for å lage en datetime
objektet er i samme ISO 8601-format, eller hvis du vet formatet du vil motta på forhånd, kan vi enkelt analysere det til en datetime
gjenstand:
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)
Å kjøre den vil skrive ut dato, klokkeslett og dato-klokkeslett:
Date: 2022-12-01
Time: 10:27:03.929149
Date-time: 2022-12-01 10:27:03.929149
Her bruker vi strptime()
metode, som godtar to argumenter:
- Den strengformaterte datoen
- Formatet til det første argumentet
Å spesifisere formatet på denne måten gjør parsingen mye raskere siden datetime
trenger ikke prøve å tolke formatet på egen hånd, som er mye dyrere beregningsmessig. Returverdien er av typen datetime
.
I vårt eksempel, "2022-12-01 10:27:03.929149"
er inngangsstrengen og "%Y-%m-%d %H:%M:%S.%f"
er formatet til datostrengen vår. Den returnerte datetime
verdien lagres som date_time_obj
.
Siden dette er en datetime
objekt, kan vi kalle date()
og time()
metoder direkte på den. Som du kan se fra utdataene, skriver den ut 'dato' og 'klokkeslett'-delen av inndatastrengen!
Formater tokens
Det er verdt å bruke et øyeblikk på å forstå formatere tokens - Den "%Y-%m-%d %H:%M:%S.%f"
fra før.
Hvert token representerer en annen del av dato-klokkeslett, som dag, måned, år, dag i måneden eller uken osv. liste over støttede tokens er omfattende nok til å muliggjøre forskjellig formatering. Noen av de ofte brukte, som vi også har brukt tidligere, er:
%Y
: År (4 sifre)%m
: Måned%d
: Dag i måneden%H
: Time (24 timer)%M
: Minutter%S
: Sekunder%f
: Mikrosekunder
OBS: Alle disse symbolene, bortsett fra året, forventes å være nullpolstret (dvs. august er den 8. måneden, og er nullpolstret til 08
).
Bruke strptime() Format Tokens for å konvertere streng til forskjellig Datetime Format
Hvis formatet til en streng er kjent, kan den enkelt analyseres til en datetime
objektet bruker strptime()
. La oss ta en titt på et ikke-trivielt eksempel som oversetter fra ett format til et annet:
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)
Inndatastrengen var av ett format – «17. juli 2022 9:20 AM». Når vi kjente til dette formatet, kartla vi de bestanddelene til ISO 8601-formatet og konverterte det til en datetime
gjenstand:
Date: 2022-07-17
Time: 09:20:00
Date-time: 2022-07-17 09:20:00
Her er en kort liste over vanlige strengformaterte datotider og deres tilsvarende formater for 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"
Du kan analysere en dato- og klokkeslettstreng av ethvert format – så lenge du bruker den riktige strengen med formattokens for inndataene du mottar.
Konverter streng til datoklokkeslett med tidssoner
Håndtering av dato og klokkeslett blir mer kompleks mens du håndterer tidssoner. Alle eksemplene ovenfor så langt er naive for tidssonen. Disse er kjent som naive datetime-objekter.
Imidlertid datetime
objekter inneholder et felt nøyaktig for lagring av tidssonerelaterte data – tzinfo
:
import datetime as dt
dtime = dt.datetime.now()
print(dtime)
print(dtime.tzinfo)
De tzinfo
felt er ment å være en datetime.timezone
objekt, som angir tidssoneinformasjonen. Det er None
som standard, og angir at datetime-objektet er tidssone-naivt. Et veldig vanlig eksternt bibliotek for håndtering av tidssoner er pytz
. Du kan stille inn PyTz objekter som tzinfo
felt også.
Hvis du ikke har det allerede – installer det via:
$ pip install pytz
Ved å bruke PyTz kan vi lage et anker for tidssone-klare datotider, for eksempel UTC:
import datetime as dt
import pytz
dtime = dt.datetime.now(pytz.utc)
print(dtime)
print(dtime.tzinfo)
Utgang:
2022-12-01 02:07:41.960920+00:00
UTC
Klokken er ikke lenger 11, men 2, fordi vi har satt tidssonen noen timer tilbake! Dette endrer tidssonen av dato og klokkeslett.
+00:00
er forskjellen mellom den viste tiden og UTC-tiden som det globale koordinasjonsankeret. Vi har satt tiden til å være i UTC, så forskyvningen er 00:00
. Dette er en tidssone-bevisst objekt.
På samme måte kan vi bytte den samme datoklokkens tolkning mellom tidssoner. La oss konvertere en streng, for eksempel "2022-06-29 17:08:00" til en datoklokke og deretter lokaliser det til «America/New_York»-tidssonen:
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)
OBS: Lokalisering gjør en tidssone-naiv datetime til en tidssone-bevisst datetime, og behandler tidssonen som den lokale. Dermed dato og klokkeslett forblir den samme, men gitt den forskjellige tidssonen, representerer den ikke lenger det samme tidspunktet ubundet fra tidssoner.
Vi får det samme datetime-verdi, oppveid av -04: 00 sammenlignet med UTC-tiden:
2022-06-29 17:08:00-04:00
America/New_York
17:08 i Tokyo er ikke samme tidspunkt som 17:08 i New York. 17:08 i Tokyo er 3:08 i New York.
Hvordan finner jeg alle tidssonekodene/aliasene?
For å finne alle tilgjengelige tidssoner, inspiser all_timezones
feltet, som er en liste over alle tilgjengelige tidssoner:
print(f'There are {len(pytz.all_timezones)} timezones in PyTzn')
for time_zone in pytz.all_timezones:
print(time_zone)
Sjekk ut vår praktiske, praktiske guide for å lære Git, med beste praksis, bransjeaksepterte standarder og inkludert jukseark. Slutt å google Git-kommandoer og faktisk lære den!
There are 594 timezones in PyTz
Africa/Abidjan
Africa/Accra
Africa/Addis_Ababa
Africa/Algiers
Africa/Asmara
Africa/Asmera
...
Endre Datetimes tidssone
Vi kan konvertere tidssonen til en tidssone-bevisst datetime
objekt fra en region til en annen, i stedet for å lokalisere en tidssone-naiv datetime gjennom linsen til en tidssone.
Dette er forskjellig fra lokalisering, ettersom lokalisering representerer et annet tidspunkt, men å konvertere tidssonen til et objekt representerer det samme tidspunktet, gjennom en annen linse:
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)
Først opprettet vi ett datetime-objekt med gjeldende tid og satte det som "America/New_York"-tidssonen. Deretter bruker du astimezone()
metoden har vi konvertert denne datetime
til tidssonen "Europa/London". Både datetime
s vil skrive ut forskjellige verdier, ved å bruke UTC-offset som en referansekobling mellom dem:
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 dagen etter i London is samme tidspunkt som 21:24 dagen før i New York ettersom London er 5 timer foran.
Som forventet er dato-tidene forskjellige siden de er omtrent 5 timer fra hverandre.
Konverter streng til Datetime ved hjelp av tredjepartsbiblioteker
Pythons datetime
modul kan konvertere alle forskjellige typer strenger til en datetime
gjenstand. Men hovedproblemet er at for å gjøre dette må du lage den riktige formateringskodestrengen som strptime()
kan forstå. Å lage denne strengen tar tid og det gjør koden vanskeligere å lese.
I stedet kan vi bruke andre tredjepartsbiblioteker for å gjøre det enklere.
I noen tilfeller har disse tredjepartsbibliotekene også bedre innebygd støtte for å manipulere og sammenligne dato-tider, og noen har til og med tidssoner innebygd, slik at du ikke trenger å inkludere en ekstra PyTz-pakke.
La oss ta en titt på noen av disse bibliotekene i de følgende delene.
Konverter streng til Datetime med dateutil
De dateutil-modul er en utvidelse av datetime
modul. En fordel er at vi ikke trenger å sende noen parsekode for å analysere en streng!
For å automatisk konvertere en streng til datetime uten et formattoken ved hjelp av Python's dateutil
:
from dateutil.parser import parse
datetime = parse('2018-06-29 22:21:41')
print(datetime)
Dette parse
funksjonen vil analysere strengen automatisk! Du trenger ikke å inkludere noen formatstreng. La oss prøve å analysere forskjellige typer strenger ved hjelp av 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')
Utgang:
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
Du kan se at nesten alle typer strenger enkelt kan analyseres ved å bruke dateutil
modul.
Selv om dette er praktisk, husk fra tidligere at å forutsi formatet gjør koden mye tregere, så hvis koden krever høy ytelse, er dette kanskje ikke den rette tilnærmingen for applikasjonen din.
Konverter streng til Datetime med Maya
Maya gjør det også veldig enkelt å analysere en streng og endre tidssoner. For enkelt å konvertere en streng med Pythons Maya:
import maya
dt = maya.parse('2018-04-29T17:45:25Z').datetime()
print(dt.date())
print(dt.time())
print(dt.tzinfo)
Utgang:
2018-04-29
17:45:25
UTC
For å konvertere tiden til en annen tidssone:
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)
Utgang:
2018-04-29
13:45:25
America/New_York
Nå er ikke det lett å bruke? La oss prøve maya
med det samme settet med strenger som vi har brukt med 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)
Utgang:
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
Som du kan se, ble alle datoformatene analysert!
Hvis vi ikke oppgir tidssoneinformasjonen, konverteres den automatisk til UTC. Så det er viktig å merke seg at vi må gi to_timezone
og naive
parametere hvis tiden ikke er i UTC.
Konverter streng til datotid med pil
arrow er et annet bibliotek for å håndtere datetime i Python. Og som før med maya
, finner den også ut dato- og tidsformatet automatisk. Når den er tolket, returnerer den en Python datetime
objekt fra arrow
gjenstand.
For enkelt å konvertere en streng til datetime ved hjelp av Python's arrow
:
import arrow
dt = arrow.get('2018-04-29T17:45:25Z')
print(dt.date())
print(dt.time())
print(dt.tzinfo)
Utgang:
2018-04-29
17:45:25
tzutc()
Og her er hvordan du kan bruke arrow
for å konvertere tidssoner ved hjelp av to()
metode:
import arrow
dt = arrow.get('2018-04-29T17:45:25Z').to('America/New_York')
print(dt)
print(dt.date())
print(dt.time())
Utgang:
2018-04-29T13:45:25-04:00
2018-04-29
13:45:25
Som du kan se er dato- og klokkeslettstrengen konvertert til "America/New_York"-regionen.
La oss nå bruke det samme settet med strenger som vi har brukt ovenfor:
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)
Denne koden vil mislykkes for dato- og klokkeslettstrengene som har blitt kommentert ut, som er over halvparten av eksemplene våre. Utgangen for andre strenger vil være:
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
For å analysere dato- og klokkeslettstrengene som er kommentert korrekt, må du sende de tilsvarende formatere tokens for å gi biblioteket ledetråder om hvordan det skal analyseres.
konklusjonen
I denne artikkelen har vi vist forskjellige måter å analysere en streng til en datetime
objekt i Python. Du kan enten velge standard Python datetime
biblioteket eller noen av tredjepartsbibliotekene nevnt i denne artikkelen, blant mange andre.
Hovedproblemet med standarden datetime
pakken er at vi må spesifisere parsingkoden manuelt for nesten alle dato- og klokkeslettstrengformater. Så hvis strengformatet ditt endres i fremtiden, må du sannsynligvis også endre koden. Men mange tredjepartsbiblioteker, som de som er nevnt her, håndterer det automatisk.
Et annet problem vi står overfor er å håndtere tidssoner. Den beste måten å håndtere dem på er alltid å lagre tiden i databasen som UTC-format og deretter konvertere den til brukerens lokale tidssone ved behov.
Disse bibliotekene er ikke bare gode for å analysere strenger, men de kan brukes til mange forskjellige typer dato- og klokkeslettrelaterte operasjoner. Jeg vil oppfordre deg til å gå gjennom dokumentene for å lære funksjonene i detalj.