Python
Completed
-
Section 1: Getting Started
-
Section 2: Core Syntax and Data Types
-
Section 3: Collections
-
39: Set Operations: Union, Intersection, Difference
-
Section 4: Control Flow
-
Section 5: Functions
-
Section 6: Turtle Graphics and Early Practice Projects
-
Section 7: Working with Files and I/O
-
Section 8: Regular Expressions
-
Section 9: Object-Oriented Python
-
Section 10: Error Handling
-
Section 11: Modules and Packages
-
Section 12: Iterators, Generators, and Functional Tools
-
Section 13: Decorators and Metaprogramming
-
Section 14: Concurrency and Parallelism
-
Section 15: Working with Dates, Times, and Numbers
-
Section 16: Standard Library Deep Dive I: Data Structures
-
Section 17: Standard Library Deep Dive II: System and Introspection
-
Section 18: Standard Library Deep Dive III: Security and Encoding
-
Section 19: Standard Library Deep Dive IV: Text and Data Utilities
-
Section 20: Networking and Web Basics
-
Section 21: Working with Databases
-
Section 22: Testing and Quality
-
Section 23: Advanced Typing
-
Section 24: Context Managers and Resource Handling
-
Section 25: Text, Unicode, and Binary Data
-
Section 26: More Functional and Iteration Tools
-
Section 27: Data Validation and Configuration
-
Section 28: Working with Images and Media
-
Section 29: Property-Based and Documentation Testing
-
Section 30: Packaging and Deployment
-
Section 31: Performance and Internals
-
Section 32: Design Patterns in Python
-
Section 33: GUI Programming
-
Section 34: Security Basics
-
Section 35: Data Structures and Algorithms
-
Section 36: Practical Projects
-
Section 37: Capstone Projects
-
Section 38: Interview and Algorithm Practice
-
Section 39: Writing Idiomatic Python
220: Working with Timedeltas
I once worked with a junior developer who was tasked with implementing a 30-day trial expiration for a SaaS product. He decided to handle it by simply adding 30 to the day attribute of the user's signup date. It worked perfectly during his testing in May. Then February rolled around, and the system started throwing ValueError: day is out of range for month. He had forgotten that dates aren't just simple integers; they're complex objects with varying month lengths and leap years. That's exactly why we have timedelta.
In Python, a timedelta represents a duration—the difference between two dates or times. Instead of trying to do the mental gymnastics of calculating how many days are left in a month, you describe the duration you want, and Python handles the calendar logic for you.
Shifting Dates Forward and Backward
When you want to find a date in the future or the past, you don't modify the datetime object directly (since they are immutable). Instead, you create a timedelta object and add or subtract it from your starting point. I usually find it cleanest to import timedelta directly from the datetime module.
from datetime import datetime, timedelta
# Let's say a user signed up right now
signup_date = datetime.now()
# Define a 30-day trial period
trial_duration = timedelta(days=30)
# Calculate the expiration date
expiration_date = signup_date + trial_duration
print(f"Signed up on: {signup_date}")
print(f"Trial expires on: {expiration_date}")
You can pass several arguments to timedelta, including weeks, days, hours, minutes, seconds, milliseconds, and microseconds. If you need to move backward in time—say, to check a user's activity over the last 24 hours—you just subtract the delta.
Measuring the Gap Between Two Events
The inverse is also true: if you subtract one datetime object from another, Python doesn't return a number; it returns a timedelta object. This is incredibly useful for calculating "time elapsed" without having to worry about the underlying Unix timestamps.
# Imagine we have a log of when a process started and ended
start_time = datetime(2023, 10, 1, 12, 0, 0)
end_time = datetime(2023, 10, 2, 14, 30, 0)
duration = end_time - start_time
print(f"The process took {duration} to complete.")
# Output: The process took 1 day, 2:30:00
The Trap of the Seconds Attribute
Here is where most developers—including myself, early in my career—trip up. A timedelta object has an attribute called .seconds. It sounds like it should give you the total length of the duration in seconds, but it doesn't. The .seconds attribute only returns the remaining seconds that didn't make it into a full day.
If your duration is 1 day and 5 seconds, .seconds will return 5, not 86405. If you need the actual total duration expressed in seconds, you must use the .total_seconds() method.
diff = timedelta(days=1, seconds=5)
print(diff.seconds) # Output: 5 (This is almost always NOT what you want)
print(diff.total_seconds()) # Output: 86405.0 (This is the actual duration)
I always tell people: unless you specifically need to isolate the "time of day" portion of a duration, avoid .seconds entirely and stick with .total_seconds(). It saves a lot of debugging headaches.
📋 Practical Task
Build a Session Timeout Validator
You are building a security feature for a web application that requires users to re-authenticate if their session has been inactive for more than 30 minutes.
Write a function called is_session_expired(last_activity_time) that does the following:
- Takes a
datetimeobject representing the last time the user performed an action. - Calculates the difference between the current time (
datetime.now()) and that activity time. - Returns
Trueif the difference is greater than 30 minutes, andFalseotherwise.
Test your function with these two cases:
# Case 1: Activity was 10 minutes ago (Should return False)
# Case 2: Activity was 45 minutes ago (Should return True)
There are no comments for now.