Understanding Python Date and Time
Bhavesh D.
July 11, 2025

Working with dates and times in Python can seem simple at first, but things get more nuanced when time zones, formatting, and differences between dates come into play. This blog explores:
- The difference between naive and aware datetime objects
- How to use datetime, timedelta, and time
- Working with timezone-aware datetime using zoneinfo and pytz
- Formatting and parsing date/time strings
- Best practices for storing datetime in databases
Let’s break this down section by section.
Naive vs Aware DateTime Objects
In Python, date/time objects fall under two categories:
- Naive: Doesn’t contain any timezone information.
- Aware: Includes timezone info (i.e., UTC offset).
Most built-in methods return naive objects unless explicitly specified.
Naive Dates Using datetime.date
import datetime
# Creating a simple date
d = datetime.date(2024, 7, 23)
print(d) # Output: 2024-07-23
# Getting today's date
dt_now = datetime.date.today()
print(dt_now) # Output: 2024-07-23
- datetime.date(year, month, day) creates a date object.
- datetime.date.today() gives the current local date.
Working with timedelta
The timedelta
object is used to perform arithmetic operations on dates.
import datetime
dt = datetime.date.today()
tdelta = datetime.timedelta(days=30)
# Adding 30 days
new_dt = dt + tdelta
print(new_dt) # Output: 2024-08-22
# Subtracting 30 days
prev_dt = dt - tdelta
print(prev_dt) # Output: 2024-06-23
You can also calculate the difference between two dates:
dt_now = datetime.date.today()
dt_end_of_year = datetime.date(2024, 12, 31)
days_remaining = dt_end_of_year - dt_now
print(days_remaining) # Output: 161 days, 0:00:00
Time Object Using datetime.time
To work with just time (without date):
import datetime
t = datetime.time(8, 5, 30)
print(t) # Output: 08:05:30
Full DateTime Object Using datetime.datetime
This combines both date and time:
import datetime
dt = datetime.datetime(2024, 7, 24, 9, 21, 30)
print(dt) # 2024-07-24 09:21:30
print(dt.date()) # 2024-07-24
print(dt.time()) # 09:21:30
You can get current datetime in various ways:
dt_today = datetime.datetime.today()
dt_now = datetime.datetime.now()
dt_utcnow = datetime.datetime.utcnow()
print(dt_today) # Local datetime
print(dt_now) # Local datetime with time
print(dt_utcnow) # UTC datetime (naive)
Note: datetime.utcnow()
returns UTC time, but it’s still a naive datetime object (tzinfo=None
).
Timezone-Aware DateTime with zoneinfo (Python 3.9+)
Python introduced the zoneinfo
module in version 3.9 for handling timezones natively.
Install tzdata (Recommended for fallback support):
pip install tzdata
Using ZoneInfo for Timezone Awareness:
from datetime import datetime
from zoneinfo import ZoneInfo
dt = datetime(2024, 7, 27, 8, 21, 24, tzinfo=ZoneInfo('Asia/Kolkata'))
print(dt) # 2024-07-27 08:21:24+05:30
# Get current UTC time
dt_utcnow = datetime.now(tz=ZoneInfo('UTC'))
print(dt_utcnow) # 2024-07-27 08:18:43.937589+00:00
# Convert to another timezone
dt_india = dt_utcnow.astimezone(ZoneInfo('Asia/Kolkata'))
print(dt_india) # 2024-07-27 13:52:43.136546+05:30
Using pytz for Timezone Localization (for older Python versions)
pip install pytz
import datetime
import pytz
dt_local = datetime.datetime(2024, 7, 20, 13, 12, 39)
india_timezone = pytz.timezone('Asia/Kolkata')
dt_aware = india_timezone.localize(dt_local)
print(dt_aware) # 2024-07-20 13:12:39+05:30
The localize()
method is essential in pytz
to convert naive datetime into timezone-aware.
Formatting and Parsing Dates
1. Format using strftime
dt = datetime.datetime.now()
print(dt.isoformat()) # 2024-07-29T14:19:44.821854
# Custom format
print(dt.strftime('%-d, %B %Y')) # 29, July 2024
For reference on all formatting options, visit: strftime.org
2. Parse string to date using strptime
dt_str = '30, July 2024'
dt = datetime.datetime.strptime(dt_str, '%d, %B %Y')
print(dt) # 2024-07-30 00:00:00
Best Practice: Store UTC in Database
When storing datetime in a database, it’s best to store it in UTC. This makes your application consistent across time zones and avoids ambiguity.
- Store: UTC datetime
- Display: Convert to user’s local timezone at runtime
Conclusion
Working with dates and times in Python requires a solid understanding of the difference between naive and aware objects. Native modules like datetime
, timedelta
, zoneinfo
, and third-party tools like pytz
make it easier to handle real-world time scenarios — from calculating durations to managing timezones across the globe.
If you’re building anything that stores or manipulates time (and most apps do), following these practices will help ensure your datetime logic is clean, accurate, and timezone-safe.
Credits:
Thanks to Corey Schafer for his excellent video tutorial on Python datetime
: Watch here