Cursus
Veel datasets uit de echte wereld bevatten datums en tijden, en een veelvoorkomende bewerking in data science is het berekenen van het tijdsverschil tussen twee tijdstippen.
De eenheden die we gebruiken om datums en tijden te meten (jaren, maanden, dagen, uren, minuten, seconden) zijn niet het eenvoudigst om mee te werken, zeker niet wanneer deze eenheden onregelmatige lengtes hebben.
Python's gegevenstype timedelta, dat deel uitmaakt van de datetime-module, neemt echter de complexiteit weg bij het berekenen van tijdsintervallen.
Laten we beginnen met een heel kort antwoord op wat Python's timedelta is en daarna verdergaan met meer details.
Wil je meer leren over datums en tijden in Python? Bekijk dan deze cursus: Working With Dates and Time in Python.
Kort antwoord: wat is Python's timedelta
De twee belangrijkste en meest gebruikte gegevenstypen uit de datetime-module zijn timedelta en datetime. Terwijl datetime-objecten specifieke tijdstippen voorstellen (bijv. 1 januari 2024 om 10:30), vertegenwoordigen timedelta-objecten de duur of het interval tussen twee tijdstippen. Zie het als het verschil tussen vragen "Wanneer?" (datetime) en "Hoe lang?" (timedelta).
Neem twee datums, die we kunnen weergeven met twee datetime-objecten. Het ene van het andere aftrekken creëert een timedelta-object dat het tijdsinterval tussen de datums voorstelt:
import datetime
first_date = datetime.datetime(year=2024, month=1, day=1)
second_date = datetime.datetime(year=2024, month=5, day=27)
interval = second_date - first_date
print(interval)
147 days, 0:00:00
De output laat zien dat de twee datums precies 147 dagen uit elkaar liggen. In het volgende voorbeeld gebruiken we de datum en tijd waarop de code wordt uitgevoerd door datetime.datetime.now() aan te roepen:
first_date = datetime.datetime(year=2024, month=1, day=1)
second_date = datetime.datetime.now()
interval = second_date - first_date
print(second_date)
print(interval)
2024-05-28 08:32:44.871646
148 days, 8:32:44.871646
Het timedelta-object laat nu de tijd zien die is verstreken tussen het begin van 2024 en de datum en tijd waarop de code wordt uitgevoerd.
We gaan Python's timedelta verder verkennen in dit artikel.
timedelta-objecten maken
In de vorige sectie hebben we een timedelta-object gemaakt uit twee datetime-objecten, maar we kunnen ook direct een tijdsinterval creëren door de constructor timedelta() aan te roepen:
interval = datetime.timedelta(days=10, seconds=3600)
print(interval)
10 days, 1:00:00
Het interval is tien dagen en één uur lang. We kunnen ook andere tijdseenheden gebruiken bij het maken van een timedelta-instantie:
interval = datetime.timedelta(weeks=1, days=3, hours=1)
print(interval)
10 days, 1:00:00
De volgende tijdseenheden zijn geldig wanneer je timedelta() aanroept:
- weeks
- days
- hours
- minutes
- seconds
- milliseconds
- microseconds
In deze tutorial duiken we dieper in hoe tijdsintervallen worden opgeslagen in een timedelta-object.
Eenvoudige rekenkunde met timedelta
We kunnen ook rekenkundige bewerkingen uitvoeren met timedelta-objecten. Beschouw de volgende drie datetime-objecten, die de releasedata vertegenwoordigen van Python 1.0, Python 2.0 en Python 3.0. Het van elkaar aftrekken van datetime-objecten creëert een timedelta-object:
release_date_python_1 = datetime.datetime(year=1991, month=2, day=20)
release_date_python_2 = datetime.datetime(year=2000, month=10, day=16)
release_date_python_3 = datetime.datetime(year=2008, month=12, day=3)
time_between_1_and_2 = release_date_python_2 - release_date_python_1
time_between_2_and_3 = release_date_python_3 - release_date_python_2
print(time_between_1_and_2)
print(time_between_2_and_3)
3526 days, 0:00:00
2970 days, 0:00:00
De output toont het aantal dagen tussen de releases van Python 1.0 en 2.0 en tussen de releases van Python 2.0 en 3.0. De tijdsintervallen zijn timedelta-objecten.
Het is ook mogelijk om optel- en aftrekbewerkingen uit te voeren tussen timedelta-objecten en datetime-objecten. Laten we een timedelta met days=100 optellen bij release_date_python_3:
print(release_date_python_3 + datetime.timedelta(days=100))
2009-03-13 00:00:00
Python 3.0 werd uitgebracht op 3 december 2008. Honderd dagen aan deze datum toevoegen brengt ons op 13 maart 2009.
We kunnen echter ook direct rekenkundige bewerkingen uitvoeren met timedelta-objecten:
print("Difference between gap 1 and gap 2")
print(time_between_1_and_2 - time_between_2_and_3)
print("Sum of gap 1 and gap 2")
print(time_between_1_and_2 + time_between_2_and_3)
Difference between gap 1 and gap 2
556 days, 0:00:00
Sum of gap 1 and gap 2
6496 days, 0:00:00
De output bevestigt dat het mogelijk is timedelta-objecten van elkaar af te trekken en op te tellen. Vermenigvuldigen en delen is ook mogelijk:
print("Multiply time interval by 3:")
print(time_between_1_and_2 * 3)
print("Divide time interval by 3:")
print(time_between_1_and_2 / 3)
Multiply time interval by 3:
10578 days, 0:00:00
Divide time interval by 3:
1175 days, 8:00:00
We kunnen timedelta-objecten ook met elkaar vergelijken:
print("Check if gap 1 is greater than gap 2")
print(time_between_1_and_2 > time_between_2_and_3)
True
De output bevestigt dat het interval tussen de releasedata van Python 1.0 en Python 2.0 langer is dan het interval tussen Python 2.0 en Python 3.0.
Belangrijke timedelta-attributen en -methoden
Een timedelta-object stelt een tijdsinterval voor door het aantal dagen, seconden en microseconden op te slaan. Deze drie eenheden zijn de enige tijdseenheden die als attributen in de timedelta-klasse worden weergegeven:
interval = datetime.timedelta(
weeks=1,
hours=10,
minutes=22,
milliseconds=1042,
)
print(f"{interval = }")
print(f"{interval.days = }")
print(f"{interval.seconds = }")
print(f"{interval.microseconds = }")
interval = datetime.timedelta(days=7, seconds=37321, microseconds=42000)
interval.days = 7
interval.seconds = 37321
interval.microseconds = 42000
Ook al bevat de aanroep van timedelta() argumenten voor weken, uren, minuten en milliseconden, de constructor zet deze eenheden om naar dagen, seconden en microseconden. De aanroepen van print() bevatten f-strings met een gelijkteken = om de variabelenaam en zijn waarde weer te geven. Je kunt meer leren over f-strings in deze tutorial over f-string formatting in Python.
Een ander handig hulpmiddel van de timedelta-klasse is de methode total_seconds(). Deze methode retourneert het totale tijdsinterval in seconden:
print("Total time interval in seconds:")
print(interval.total_seconds())
Total time interval in seconds:
642121.042
Deze waarde stelt het volledige tijdsinterval in seconden voor. Het is niet hetzelfde als de waarde van .seconds, die alleen het secondencomponent van het interval laat zien zonder rekening te houden met de dagen en microseconden.
We kunnen de waarde die wordt teruggegeven door .total_seconds() gebruiken om het tijdsinterval naar elke andere eenheid om te rekenen:
print("Total time interval in days:")
print(interval.total_seconds() / 3600 / 24)
Total time interval in days:
7.431956504629629
De output toont het tijdsinterval in dagen, omdat de waarde die .total_seconds() teruggeeft, wordt gedeeld door het aantal seconden in een uur en het aantal uren in een dag.
timedelta-voorbeeld: groei berekenen
Laten we naar een voorbeeld kijken. De online winkel van een bedrijf dat Python-boeken verkoopt, logt alle verkopen. Dit zijn de gegevens voor één klant:
data = {
"customer_id": 3542,
"sales": [
{"date": "2024-04-21T13:23:45", "price": 24.99, "quantity": 1},
{"date": "2024-02-13T10:54:12", "price": 24.99, "quantity": 2},
{"date": "2024-01-08T20:32:24", "price": 18.99, "quantity": 1},
],
}
We moeten het tijdsverschil berekenen tussen de eerste en laatste bestelling van een klant. De bestellingen staan altijd in chronologische volgorde in de lijst met alle verkopen.
Onze eerste stap is om de datums uit deze geneste structuur te halen en ze om te zetten naar datetime-objecten. Gelukkig staan de tijdstempels in de standaard ISO 8601-indeling (YYYY-MM-DDTHH:MM:SS), dus we kunnen de handige methode fromisoformat() gebruiken:
sales = data["sales"]
dates = []
for item in sales:
date = datetime.datetime.fromisoformat(item["date"])
dates.append(date)
print(dates)
[datetime.datetime(2024, 4, 21, 13, 23, 45), datetime.datetime(2024, 2, 13, 10, 54, 12), datetime.datetime(2024, 1, 8, 20, 32, 24)]
De lijst dates bevat datetime-objecten met de datums van elke bestelling. Ten slotte kunnen we het tijdsinterval tussen de eerste en laatste bestelling berekenen:
time_span = dates[0] - dates[-1]
print(time_span)
print(time_span.days)
103 days, 16:51:21
103
Het verschil tussen de eerste en laatste datum levert een timedelta-object op. De code toont time_span, waarin het aantal dagen, uren, minuten en seconden wordt weergegeven. We tonen ook time_span.days om alleen het gehele aantal dagen te laten zien.
Wil je meer leren over het omzetten van strings naar datetime? Bekijk dan deze tutorial over Python String to Datetime.
Snelle tips bij het gebruik van timedelta
Hier zijn een paar zaken om in gedachten te houden wanneer je Python's timedelta gebruikt:
1. Gebruik bij voorkeur keyword-argumenten wanneer je timedelta() aanroept om fouten met eenheden te voorkomen:
interval = datetime.timedelta(weeks=1, days=3, hours=1, milliseconds=1354)
2. Wanneer je een tijdsinterval zoekt tussen twee datums in verschillende tijdzones, zet timedelta de datums om naar UTC voordat het het tijdsverschil berekent:
import zoneinfo
some_date = datetime.datetime.fromisoformat("2024-01-01T00:00:00")
some_date_lon = some_date.replace(tzinfo=zoneinfo.ZoneInfo("Europe/London"))
some_date_nyc = some_date.replace(tzinfo=zoneinfo.ZoneInfo("America/New_York"))
print(some_date_lon)
print(some_date_nyc)
print(some_date_nyc - some_date_lon)
2024-01-01 00:00:00+00:00
2024-01-01 00:00:00-05:00
5:00:00
De datum in some_date toont het begin van het nieuwe jaar. Dit is een naïef datetime-object omdat het geen informatie heeft over de tijdzone. some_date_lon en some_date_nyc zijn echter aware datetime-objecten omdat ze het begin van het nieuwe jaar in respectievelijk Londen en New York voorstellen.
De timedelta die wordt verkregen door de twee aware datetime-objecten van elkaar af te trekken, toont een tijdsinterval van vijf uur, wat het UTC-tijdsverschil is.
3. Zomertijdwijzigingen worden niet meegenomen door timedelta:
nyc = zoneinfo.ZoneInfo("America/New_York")
first_time = datetime.datetime.strptime("2024-03-10 1:00am", "%Y-%m-%d %I:%M%p")
first_time = first_time.replace(tzinfo=nyc)
second_time = datetime.datetime.strptime("2024-03-10 3:00am", "%Y-%m-%d %I:%M%p")
second_time = second_time.replace(tzinfo=nyc)
time_difference = second_time - first_time
print("Time difference between the first and second time:")
print(time_difference)
print("Checking the DST status of the first and second time:")
print(f"{first_time.dst() = }")
print(f"{second_time.dst() = }")
Time difference between the first and second time:
2:00:00
Checking the DST status of the first and second time:
first_time.dst() = datetime.timedelta(0)
second_time.dst() = datetime.timedelta(seconds=3600)
De twee tijden stellen 1:00 a.m. en 3:00 a.m. voor op 3 maart 2024 in New York. Zomertijd begon om 2:00 a.m. op dezelfde dag, waarbij de klok vooruitging naar 3:00 a.m. Het verschil tussen de twee tijden geeft een timedelta van twee uur, ook al is er door de start van de zomertijd slechts één uur verstreken tussen de twee tijdstippen.
We kunnen naar UTC omrekenen als we de werkelijke verstreken tijd nodig hebben:
first_time_utc = first_time.astimezone(zoneinfo.ZoneInfo("UTC"))
second_time_utc = second_time.astimezone(zoneinfo.ZoneInfo("UTC"))
time_difference_utc = second_time_utc - first_time_utc
print("Actual time difference between the first and second time:")
print(time_difference_utc)
Actual time difference between the first and second time:
1:00:00
Converteren naar UTC vóór het aftrekken van de datetime-objecten geeft de daadwerkelijke tijd tussen de twee datetime-objecten.
Conclusie
Python's timedelta-klasse biedt eenvoudige manieren om met tijdsintervallen om te gaan, waardoor het makkelijker wordt om met perioden in verschillende eenheden te werken. We hebben bekeken hoe je timedelta-objecten maakt en er rekenkundige bewerkingen mee uitvoert, waaronder optellen, aftrekken, vermenigvuldigen en delen.
Je kunt meer lezen over het werken met datums en tijden in de volgende artikelen:
Ik studeerde natuurkunde en wiskunde op bachelorniveau aan de Universiteit van Malta. Daarna verhuisde ik naar Londen en behaalde ik mijn PhD in natuurkunde aan Imperial College. Ik werkte aan nieuwe optische technieken om het menselijk netvlies in beeld te brengen. Nu richt ik me op schrijven over Python, communiceren over Python en lesgeven in Python.

