Beskrivning
Data kan representeras i olika former – och ett bekvämt sätt att representera datum och tider är strängar. Men för att arbeta med dessa datum och tider på ett aritmetiskt sätt (som att beräkna tidsskillnader, lägga till eller ta bort tid, etc.) – måste vi konvertera dem till en datetime
objekt.
En av de vanligaste källorna till strängformaterade datumtider är REST API:er som returnerar agnostiska strängar, som vi sedan kan konvertera till andra format.
Dessutom – tidszoner är en vanlig huvudvärk när det gäller att arbeta med datetime-objekt, så vi måste tänka på det när vi konverterar också.
I den här guiden tar vi en titt på hur man konverterar ett strängdatum/-tid till ett
datetime
objekt i Python, med den inbyggdadatetime
modul, men även tredjepartsmoduler som t.exdateutil
,arrow
och Maya, som står för tidszoner.
Konvertera strängar med datumtid
Smakämnen datum Tid Modulen består av tre olika objekttyper: date
, time
och datetime
. De date
objektet håller datumet, time
håller tiden, och datetime
håller både datum och tid!
import datetime
print(f'Current date/time: {datetime.datetime.now()}')
Att köra den här koden skulle resultera i:
Current date/time: 2022-12-01 10:27:03.929149
När ingen anpassad formatering anges används standardsträngformatet, dvs formatet för "2022-12-01 10:27:03.929149" är i ISO 8601
format (ÅÅÅÅ-MM-DDTHH:MM:SS.mmmmmm). Om vår inmatningssträng för att skapa en datetime
objektet är i samma ISO 8601-format eller om du vet vilket format du kommer att få i förväg kan vi enkelt analysera det till en datetime
objekt:
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)
Om du kör det kommer att skriva ut datum, tid och datum-tid:
Date: 2022-12-01
Time: 10:27:03.929149
Date-time: 2022-12-01 10:27:03.929149
Här använder vi strptime()
metod, som accepterar två argument:
- Det strängformaterade datumet
- Formatet för det första argumentet
Att specificera formatet på det här sättet gör analysen mycket snabbare sedan dess datetime
behöver inte försöka tolka formatet på egen hand, vilket är mycket dyrare beräkningsmässigt. Returvärdet är av typen datetime
.
I vårt exempel, "2022-12-01 10:27:03.929149"
är inmatningssträngen och "%Y-%m-%d %H:%M:%S.%f"
är formatet på vår datumsträng. Den återvände datetime
värde lagras som date_time_obj
.
Eftersom detta är en datetime
objekt kan vi kalla date()
och time()
metoder direkt på den. Som du kan se från utdata, skriver den ut "datum" och "tid" delen av inmatningssträngen!
Formatera tokens
Det är värt att ta en stund att förstå formatera tokens - Den "%Y-%m-%d %H:%M:%S.%f"
från tidigare.
Varje token representerar en annan del av datum-tid, som dag, månad, år, dag i månaden eller veckan, etc. lista över tokens som stöds är tillräckligt omfattande för att möjliggöra olika formatering. Några av de vanligaste som vi också har använt tidigare är:
%Y
: År (4 siffror)%m
: Månad%d
: Dag i månaden%H
: timme (24 timmar)%M
: Minuter%S
: Sekunder%f
: Mikrosekunder
Notera: Alla dessa polletter, förutom året, förväntas vara nollstoppade (dvs. augusti är den 8:e månaden och är nollstoppad till 08
).
Använda strptime() Format Tokens för att konvertera sträng till ett annat Datetime Format
Om formatet för en sträng är känt kan den enkelt tolkas till en datetime
objekt med strptime()
. Låt oss ta en titt på ett icke-trivialt exempel som översätts från ett format till ett annat:
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)
Inmatningssträngen hade ett format – "17 juli 2022 9:20 AM". Genom att känna till detta format mappade vi de ingående elementen till ISO 8601-formatet och konverterade det till en datetime
objekt:
Date: 2022-07-17
Time: 09:20:00
Date-time: 2022-07-17 09:20:00
Här är en kort lista över vanliga strängformaterade datumtider och deras motsvarande format för 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 analysera en datum-tid-sträng av vilket format som helst – så länge du använder rätt sträng med formattokens för den inmatning du tar emot.
Konvertera sträng till datumtid med tidszoner
Hantering av datum-tider blir mer komplex när man hanterar tidszoner. Alla ovanstående exempel hittills är naiva för tidszonen. Dessa är kända som naiva datetime-objekt.
Emellertid den datetime
objekt innehåller ett fält exakt för att lagra tidszonrelaterad data – tzinfo
:
import datetime as dt
dtime = dt.datetime.now()
print(dtime)
print(dtime.tzinfo)
Smakämnen tzinfo
fältet är tänkt att vara en datetime.timezone
objekt, som anger tidszonsinformationen. Dess None
som standard och anger att datetime-objektet är tidszonsnaivt. Ett mycket vanligt externt bibliotek för hantering av tidszoner är pytz
. Du kan ställa in PyTz föremål som tzinfo
fält också.
Om du inte redan har det – installera det via:
$ pip install pytz
Med PyTz kan vi skapa ett ankare för tidszonsmedvetna datumtider, såsom UTC:
import datetime as dt
import pytz
dtime = dt.datetime.now(pytz.utc)
print(dtime)
print(dtime.tzinfo)
Produktion:
2022-12-01 02:07:41.960920+00:00
UTC
Klockan är inte längre 11:2, utan XNUMX:XNUMX, eftersom vi har ställt in tidszonen några timmar tillbaka! Detta ändrar tidszonen av datum och tid.
+00:00
är skillnaden mellan den visade tiden och UTC-tiden som globalt koordinationsankare. Vi har ställt in tiden i UTC, så offset är det 00:00
. Detta är en tidszonsmedvetet objekt.
På samma sätt kan vi byta tolkning av samma datum och tid mellan tidszoner. Låt oss konvertera en sträng, till exempel "2022-06-29 17:08:00" till en datumtid och sedan lokalisera det till "America/New_York" tidszon:
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)
Notera: Lokalisering förvandlar en tidszonsnaiv datetime till en tidszonsmedveten datetime och behandlar tidszonen som den lokala. Alltså datetime förblir detsamma, men med tanke på den olika tidszonen representerar den inte längre samma tidpunkt obunden från tidszoner.
Vi får samma sak datetime värde, kompenseras av -04: 00 jämfört med UTC-tiden:
2022-06-29 17:08:00-04:00
America/New_York
17:08 i Tokyo är inte samma tidpunkt som 17:08 i New York. 17:08 i Tokyo är 3:08 i New York.
Hur hittar jag alla tidszonskoder/alias?
För att hitta alla tillgängliga tidszoner, inspektera all_timezones
fältet, som är en lista över alla tillgängliga tidszoner:
print(f'There are {len(pytz.all_timezones)} timezones in PyTzn')
for time_zone in pytz.all_timezones:
print(time_zone)
Kolla in vår praktiska, praktiska guide för att lära dig Git, med bästa praxis, branschaccepterade standarder och medföljande fuskblad. Sluta googla Git-kommandon och faktiskt lära Det!
There are 594 timezones in PyTz
Africa/Abidjan
Africa/Accra
Africa/Addis_Ababa
Africa/Algiers
Africa/Asmara
Africa/Asmera
...
Ändra Datetimes tidszon
Vi kan konvertera tidszon för en tidszonsmedveten datetime
objekt från en region till en annan, istället för att lokalisera en tidszon-naiv datetime genom linsen för någon tidszon.
Detta skiljer sig från lokalisering, eftersom lokalisering representerar en annan tidpunkt, men att konvertera ett objekts tidszon representerar samma tidpunkt, genom en annan lins:
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 skapade vi ett datetime-objekt med den aktuella tiden och ställde in det som tidszonen "America/New_York". Använd sedan astimezone()
metod har vi konverterat detta datetime
till tidszonen "Europa/London". Både datetime
s kommer att skriva ut olika värden, med UTC-offset som referenslänk mellan 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 nästa dag i London is samma tidpunkt som 21:24 föregående dag i New York eftersom London ligger 5 timmar före.
Som väntat är datum-tiderna olika eftersom de skiljer sig cirka 5 timmar.
Konvertera sträng till datumtid med hjälp av tredjepartsbibliotek
Pythons datetime
modul kan konvertera alla olika typer av strängar till en datetime
objekt. Men huvudproblemet är att för att göra detta måste du skapa lämplig formateringskodsträng som strptime()
kan förstå. Att skapa denna sträng tar tid och det gör koden svårare att läsa.
Istället kan vi använda andra tredjepartsbibliotek för att göra det enklare.
I vissa fall har dessa tredjepartsbibliotek också bättre inbyggt stöd för att manipulera och jämföra datum-tider, och vissa har till och med tidszoner inbyggda, så du behöver inte inkludera ett extra PyTz-paket.
Låt oss ta en titt på några av dessa bibliotek i följande avsnitt.
Konvertera sträng till Datetime med dateutil
Smakämnen dateutil-modul är en förlängning av datetime
modul. En fördel är att vi inte behöver skicka någon analyskod för att analysera en sträng!
För att automatiskt konvertera en sträng till datetime utan ett formattoken med Pythons dateutil
:
from dateutil.parser import parse
datetime = parse('2018-06-29 22:21:41')
print(datetime)
Denna parse
funktion kommer att analysera strängen automatiskt! Du behöver inte inkludera någon formatsträng. Låt oss försöka analysera olika typer av strängar med hjälp 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')
Produktion:
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 att nästan alla typer av strängar lätt kan analyseras med hjälp av dateutil
modul.
Även om detta är bekvämt, kom ihåg från tidigare att att behöva förutsäga formatet gör koden mycket långsammare, så om din kod kräver hög prestanda så kanske detta inte är rätt tillvägagångssätt för din applikation.
Konvertera sträng till Datetime med Maya
maya gör det också mycket enkelt att analysera en sträng och ändra tidszoner. För att enkelt konvertera en sträng med Pythons Maya:
import maya
dt = maya.parse('2018-04-29T17:45:25Z').datetime()
print(dt.date())
print(dt.time())
print(dt.tzinfo)
Produktion:
2018-04-29
17:45:25
UTC
För att konvertera tiden till en annan tidszon:
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)
Produktion:
2018-04-29
13:45:25
America/New_York
Är det inte så lätt att använda nu? Låt oss prova maya
med samma uppsättning strängar som vi har använt 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)
Produktion:
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, analyserades alla datumformat framgångsrikt!
Om vi inte tillhandahåller tidszonsinformationen konverterar den automatiskt den till UTC. Så det är viktigt att notera att vi måste ge to_timezone
och naive
parametrar om tiden inte är i UTC.
Konvertera sträng till datumtid med pil
arrow är ett annat bibliotek för att hantera datetime i Python. Och som tidigare med maya
, räknar den också ut datumformatet automatiskt. När den har tolkats returnerar den en Python datetime
objekt från arrow
objekt.
För att enkelt konvertera en sträng till datetime med Pythons arrow
:
import arrow
dt = arrow.get('2018-04-29T17:45:25Z')
print(dt.date())
print(dt.time())
print(dt.tzinfo)
Produktion:
2018-04-29
17:45:25
tzutc()
Och här är hur du kan använda arrow
för att konvertera tidszoner med hjälp av to()
metod:
import arrow
dt = arrow.get('2018-04-29T17:45:25Z').to('America/New_York')
print(dt)
print(dt.date())
print(dt.time())
Produktion:
2018-04-29T13:45:25-04:00
2018-04-29
13:45:25
Som du kan se konverteras datum-tid-strängen till regionen "America/New_York".
Nu, låt oss återigen använda samma uppsättning strängar som vi har använt ovan:
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)
Den här koden kommer att misslyckas för de datum-tid-strängar som har kommenterats bort, vilket är över hälften av våra exempel. Utdata för andra strängar kommer att vara:
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
För att korrekt analysera datum- och tidsträngarna som kommenteras ut måste du skicka motsvarande formatera tokens för att ge biblioteket ledtrådar om hur man analyserar det.
Slutsats
I den här artikeln har vi visat olika sätt att tolka en sträng till en datetime
objekt i Python. Du kan antingen välja standard Python datetime
biblioteket eller något av de tredjepartsbibliotek som nämns i den här artikeln, bland många andra.
Det största problemet med standarden datetime
paketet är att vi måste specificera analyskoden manuellt för nästan alla datum-tid-strängformat. Så om ditt strängformat ändras i framtiden måste du troligen också ändra din kod. Men många tredjepartsbibliotek, som de som nämns här, hanterar det automatiskt.
Ytterligare ett problem vi står inför är att hantera tidszoner. Det bästa sättet att hantera dem är att alltid lagra tiden i din databas som UTC-format och sedan konvertera den till användarens lokala tidszon vid behov.
Dessa bibliotek är inte bara bra för att analysera strängar, utan de kan användas för många olika typer av datum-tid-relaterade operationer. Jag skulle uppmuntra dig att gå igenom dokumenten för att lära dig funktionerna i detalj.