Strings converteren naar datetime in Python

Introductie

Gegevens kunnen in verschillende vormen worden weergegeven - en dat is een handige manier om datums en tijden weer te geven strings. Om echter op een rekenkundige manier met deze datums en tijden te werken (zoals tijdsverschillen berekenen, tijd toevoegen of verwijderen, enz.) moeten we ze converteren naar een datetime voorwerp.

Een van de meest voorkomende bronnen van string-geformatteerde datetimes zijn REST API's die agnostische tekenreeksen retourneren, die we vervolgens naar andere indelingen kunnen converteren.

Bovendien zijn tijdzones een veel voorkomende hoofdpijn als het gaat om het werken met datetime-objecten, dus daar moeten we ook aan denken tijdens het converteren.

In deze handleiding zullen we bekijken hoe u een tekenreeksdatum/-tijd converteert naar een datetime object in Python, met behulp van de ingebouwde datetime module, maar ook modules van derden zoals dateutil, arrow en Maya, rekening houdend met tijdzones.

Tekenreeksen converteren met behulp van datetime

De datetime module bestaat uit drie verschillende objecttypes: date, time en datetime. De date object bevat de datum, time houdt de tijd vast, en datetime bevat zowel datum als tijd!

import datetime
print(f'Current date/time: {datetime.datetime.now()}')

Het uitvoeren van deze code zou resulteren in:

Current date/time: 2022-12-01 10:27:03.929149

Als er geen aangepaste opmaak is opgegeven, wordt de standaard tekenreeksindeling gebruikt, dwz de indeling voor "2022-12-01 10:27:03.929149" is in ISO 8601 formaat (JJJJ-MM-DDTUU:MM:SS.mmmmmm). Als onze invoerreeks om een datetime object is in dezelfde ISO 8601-indeling of als u van tevoren weet welke indeling u ontvangt, kunnen we het gemakkelijk ontleden naar een datetime voorwerp:

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)

Als u het uitvoert, worden de datum, tijd en datum-tijd afgedrukt:

Date: 2022-12-01
Time: 10:27:03.929149
Date-time: 2022-12-01 10:27:03.929149

Hier gebruiken we de strptime() methode, die twee argumenten accepteert:

  • De datum in tekenreeksindeling
  • De indeling van het eerste argument

Door het formaat op deze manier op te geven, wordt het ontleden sindsdien veel sneller datetime hoeft niet te proberen het formaat zelf te interpreteren, wat rekenkundig veel duurder is. De geretourneerde waarde is van het type datetime.

In ons voorbeeld "2022-12-01 10:27:03.929149" is de invoertekenreeks en "%Y-%m-%d %H:%M:%S.%f" is het formaat van onze datumreeks. De teruggekeerden datetime waarde wordt opgeslagen als date_time_obj.

Omdat dit een datetime object, kunnen we de noemen date() en time() methodes er direct op. Zoals je kunt zien aan de uitvoer, wordt het 'datum'- en 'tijd'-gedeelte van de invoerreeks afgedrukt!

Tokens opmaken

Het is de moeite waard om even de tijd te nemen om het te begrijpen tokens opmaken - De "%Y-%m-%d %H:%M:%S.%f" van vroeger.

Elk token vertegenwoordigt een ander deel van de datum-tijd, zoals dag, maand, jaar, dag van de maand of week, enz. De lijst met ondersteunde tokens is uitgebreid genoeg om verschillende opmaak mogelijk te maken. Enkele veelgebruikte, die we ook eerder hebben gebruikt, zijn:

  • %Y: Jaar (4 cijfers)
  • %m: Maand
  • %d: Dag van de maand
  • %H: Uur (24 uur)
  • %M: Minuten
  • %S: Seconden
  • %f: Microseconden

Opmerking: Van al deze tokens, behalve het jaar, wordt verwacht dat ze nul-opgevuld zijn (dat wil zeggen, augustus is de 8e maand en is nul-opgevuld tot 08).

Tokens voor strptime()-indeling gebruiken om tekenreeksen naar een ander datum/tijd-formaat te converteren

Als het formaat van een tekenreeks bekend is, kan deze eenvoudig worden geparseerd naar een datetime object met behulp van strptime(). Laten we eens kijken naar een niet-triviaal voorbeeld dat zich vertaalt van het ene formaat naar het andere:

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)

De invoerreeks had รฉรฉn indeling: "17 juli 2022 9:20 uur". Omdat we dit formaat kenden, hebben we de samenstellende elementen toegewezen aan het ISO 8601-formaat en omgezet naar een datetime voorwerp:

Date: 2022-07-17
Time: 09:20:00
Date-time: 2022-07-17 09:20:00

Hier is een korte lijst met veelgebruikte datum- en tijdsindelingen in tekenreeksen en de bijbehorende indelingen voor 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"

U kunt een datum-tijdreeks van elk formaat ontleden, zolang u de juiste reeks formaattokens gebruikt voor de invoer die u ontvangt.

Converteer String naar Datetime met tijdzones

Het omgaan met datum-tijden wordt complexer bij het omgaan met tijdzones. Alle bovenstaande voorbeelden tot nu toe zijn naรฏef voor de tijdzone. Deze staan โ€‹โ€‹bekend als naรฏeve datetime-objecten.

De datetime objecten bevatten precies een veld voor het opslaan van tijdzonegerelateerde gegevens - tzinfo:

import datetime as dt
dtime = dt.datetime.now()

print(dtime) 
print(dtime.tzinfo) 

De tzinfo veld is bedoeld als een datetime.timezone object, waarmee de tijdzone-informatie wordt aangegeven. Zijn None standaard, en geeft aan dat het datetime-object tijdzone-naรฏef is. Een veelgebruikte externe bibliotheek voor het afhandelen van tijdzones is pytzโ€‹ U kunt instellen PyTz objecten als de tzinfo veld ook.

Als je het nog niet hebt, installeer het dan via:

$ pip install pytz

Met behulp van PyTz kunnen we een anker maken voor tijdzonebewuste datetimes, zoals UTC:

import datetime as dt
import pytz

dtime = dt.datetime.now(pytz.utc)

print(dtime)
print(dtime.tzinfo)

Output:

2022-12-01 02:07:41.960920+00:00
UTC

Het is niet langer 11 uur, maar 2 uur, omdat we de tijdzone een paar uur terug hebben gezet! Dit verandert de tijdzone van de datumtijd.

+00:00 is het verschil tussen de weergegeven tijd en de UTC-tijd als het globale coรถrdinatieanker. We hebben de tijd ingesteld op UTC, dus de offset is 00:00. Dit is een tijdzonebewust object.

Op dezelfde manier kunnen we de interpretatie van dezelfde datetime schakelen tussen tijdzones. Laten we een string converteren, zoals "2022-06-29 17:08:00" naar een datum/tijd en dan lokaliseren het naar de tijdzone "America/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)

Opmerking: Lokalisatie verandert een tijdzone-naรฏeve datetime in een tijdzone-bewuste datetime, en behandelt de tijdzone als de lokale. Dus de datumtijd blijft hetzelfde, maar gezien de verschillende tijdzones vertegenwoordigt het niet langer hetzelfde tijdstip dat niet gebonden is aan tijdzones.

Wij krijgen hetzelfde datum/tijd waarde, gecompenseerd door -04: 00 vergeleken met de UTC-tijd:

2022-06-29 17:08:00-04:00
America/New_York

17:08 in Tokio is niet hetzelfde tijdstip als 17:08 in New York. 17:08 in Tokio is 3:08 in New York.

Hoe vind ik alle tijdzonecodes/aliassen?

Om alle beschikbare tijdzones te vinden, inspecteert u de all_timezones veld, dat een lijst is van alle beschikbare tijdzones:

print(f'There are {len(pytz.all_timezones)} timezones in PyTzn')
for time_zone in pytz.all_timezones:
   print(time_zone)

Bekijk onze praktische, praktische gids voor het leren van Git, met best-practices, door de industrie geaccepteerde normen en bijgevoegd spiekbriefje. Stop met Googlen op Git-commando's en eigenlijk leren het!

There are 594 timezones in PyTz

Africa/Abidjan
Africa/Accra
Africa/Addis_Ababa
Africa/Algiers
Africa/Asmara
Africa/Asmera
...

Wijzig de tijdzone van Datetime

We kunnen de tijdzone van een tijdzonebewust converteren datetime object van de ene regio naar de andere, in plaats van een tijdzone-naรฏeve datetime te lokaliseren door de lens van een bepaalde tijdzone.

Dit verschilt van lokalisatie, aangezien lokalisatie een ander tijdstip vertegenwoordigt, maar het converteren van de tijdzone van een object vertegenwoordigt hetzelfde tijdstip, door een andere lens:

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)

Eerst hebben we รฉรฉn datetime-object gemaakt met de huidige tijd en deze ingesteld als de tijdzone "America/New_York". Gebruik dan de astimezone() methode hebben we dit omgezet datetime naar de tijdzone "Europa/Londen". Beide datetimes zal verschillende waarden afdrukken, met UTC-offset als een referentielink daartussen:

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 de volgende dag in Londen is hetzelfde tijdstip als 21:24 de vorige dag in New York want Londen ligt 5 uur voor.

Zoals verwacht zijn de datum-tijden anders omdat ze ongeveer 5 uur uit elkaar liggen.

Converteer tekenreeks naar Datetime met behulp van bibliotheken van derden

Python's datetime module kan alle verschillende soorten strings converteren naar een datetime voorwerp. Maar het grootste probleem is dat je om dit te doen de juiste opmaakcodereeks moet maken die strptime() kunnen begrijpen. Het maken van deze string kost tijd en maakt de code moeilijker te lezen.

In plaats daarvan kunnen we andere bibliotheken van derden gebruiken om het gemakkelijker te maken.

In sommige gevallen hebben deze bibliotheken van derden ook betere ingebouwde ondersteuning voor het manipuleren en vergelijken van datum-tijden, en sommige hebben zelfs ingebouwde tijdzones, dus u hoeft geen extra PyTz-pakket toe te voegen.

Laten we een paar van deze bibliotheken bekijken in de volgende secties.

Converteer String naar Datetime met dateutil

De dateutil-module is een uitbreiding op de datetime moduul. Een voordeel is dat we geen ontledingscode hoeven door te geven om een โ€‹โ€‹string te ontleden!

Om automatisch een string naar datetime te converteren zonder een formaattoken met behulp van Python's dateutil:

from dateutil.parser import parse
datetime = parse('2018-06-29 22:21:41')

print(datetime)

Deze parse functie zal de string automatisch ontleden! U hoeft geen opmaaktekenreeks op te nemen. Laten we proberen verschillende soorten strings te ontleden met behulp van 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')

Output:

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

U kunt zien dat bijna elk type string eenvoudig kan worden geparseerd met behulp van de dateutil module.

Hoewel dit handig is, herinnert u zich van eerder dat het moeten voorspellen van de indeling de code veel langzamer maakt, dus als uw code hoge prestaties vereist, is dit misschien niet de juiste benadering voor uw toepassing.

Converteer String naar Datetime met Maya

Maya maakt het ook heel gemakkelijk om een โ€‹โ€‹string te ontleden en tijdzones te wijzigen. Om eenvoudig een string te converteren met Python's Maya:

import maya

dt = maya.parse('2018-04-29T17:45:25Z').datetime()
print(dt.date())
print(dt.time())
print(dt.tzinfo)

Output:

2018-04-29
17:45:25
UTC

Voor het omzetten van de tijd naar een andere tijdzone:

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)

Output:

2018-04-29
13:45:25
America/New_York

Is het gebruik nu niet zo eenvoudig? Laten we uitproberen maya met dezelfde reeks snaren die we hebben gebruikt 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)
    
    
    
    

Output:

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

Zoals u kunt zien, zijn alle datumnotaties met succes geparseerd!

Als we de tijdzone-informatie niet verstrekken, wordt deze automatisch geconverteerd naar UTC. Het is dus belangrijk op te merken dat we Dan moet je lever de to_timezone en naive parameters als de tijd niet in UTC is.

Converteer String naar Datetime met Arrow

pijl is een andere bibliotheek voor het omgaan met datetime in Python. En zoals voorheen met maya, berekent het ook automatisch het datum/tijd-formaat. Eenmaal geรฏnterpreteerd, retourneert het een Python datetime object uit de arrow voorwerp.

Om eenvoudig een string naar datetime te converteren met Python's arrow:

import arrow

dt = arrow.get('2018-04-29T17:45:25Z')
print(dt.date())
print(dt.time())
print(dt.tzinfo)

Output:

2018-04-29
17:45:25
tzutc()

En hier is hoe u kunt gebruiken arrow om tijdzones te converteren met behulp van de to() methode:

import arrow

dt = arrow.get('2018-04-29T17:45:25Z').to('America/New_York')
print(dt)
print(dt.date())
print(dt.time())

Output:

2018-04-29T13:45:25-04:00
2018-04-29
13:45:25

Zoals u kunt zien, wordt de datum-tijdreeks geconverteerd naar de regio "America/New_York".

Laten we nu opnieuw dezelfde set strings gebruiken die we hierboven hebben gebruikt:

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)
    
    
    
    

Deze code zal mislukken voor de datum-tijdreeksen die zijn becommentarieerd, wat meer dan de helft van onze voorbeelden is. De uitvoer voor andere strings zal zijn:

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

Om de datum-tijdreeksen die zijn uitgecommentarieerd, correct te ontleden, moet u de corresponderende tokens opmaken om de bibliotheek aanwijzingen te geven over hoe het te ontleden.

Conclusie

In dit artikel hebben we verschillende manieren laten zien om een โ€‹โ€‹string te ontleden naar een datetime object in Python. U kunt kiezen voor de standaard Python datetime bibliotheek of een van de bibliotheken van derden die in dit artikel worden genoemd, naast vele andere.

Het grootste probleem met de standaard datetime pakket is dat we de parseercode handmatig moeten specificeren voor bijna alle datum-tijd tekenreeksformaten. Dus als uw tekenreeksformaat in de toekomst verandert, zult u waarschijnlijk ook uw code moeten wijzigen. Maar veel bibliotheken van derden, zoals de hier genoemde, verwerken dit automatisch.

Een ander probleem waarmee we worden geconfronteerd, is het omgaan met tijdzones. De beste manier om hiermee om te gaan, is altijd door de tijd in uw database op te slaan in UTC-indeling en deze vervolgens naar de lokale tijdzone van de gebruiker te converteren wanneer dat nodig is.

Deze bibliotheken zijn niet alleen goed voor het ontleden van tekenreeksen, maar ze kunnen ook worden gebruikt voor veel verschillende soorten datum-tijdgerelateerde bewerkingen. Ik raad u aan de documenten door te nemen om de functionaliteiten in detail te leren kennen.

Tijdstempel:

Meer van Stapelmisbruik