Konvertering av strenger til datoklokkeslett i Python

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 innebygde datetime modul, men også tredjepartsmoduler som f.eks dateutil, 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, timeog 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 datetimes 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 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.

Tidstempel:

Mer fra Stackabuse