Dates and Times in Python
Python's standard datetime module handles dates, times and the time between them. Its date class holds a calendar day, datetime adds a time of day, and timedelta measures a length of time, such as 30 days, that you can add to a date.
Key facts
date.today()returns the current date, anddatetime.now()returns the current date and time.date(2026, 10, 28)prints as2026-10-28, the ISO 8601 format.strftime("%d/%m/%Y")formats a date as text, andstrptime()parses text into a datetime.- Subtracting one date from another gives a
timedelta, and its.daysattribute holds the number of days. datetime.now(timezone.utc)returns the current time in UTC with its offset attached.
What is the datetime module in Python?
The datetime module comes with Python and handles dates and times. Import the classes you need from it, such as date for a calendar day and datetime for a day with a time.
from datetime import date, datetime
launch = date(2026, 10, 28)
meeting = datetime(2026, 10, 28, 14, 30)
print(launch)
print(meeting)
print(launch.year, launch.month, launch.day)2026-10-28 2026-10-28 14:30:00 2026 10 28
Both print the year first, then the month and the day, in the order of ISO 8601, the international date standard, so the text sorts in date order.
The module and one of its classes share the name datetime, which is why the common first line from datetime import datetime says it twice. The modules and imports lesson compares the two import forms.
How do I get today's date in Python?
Call date.today() for the date, or datetime.now() for the date and the time. Both read the computer's clock in its local time zone.
from datetime import date, datetime
print(date.today())
print(datetime.now())2026-10-28 2026-10-28 22:53:39.750870
The runner uses your browser's clock and time zone, so each run shows your own date and time. The six digits after the seconds are microseconds.
date.today() and datetime.now() are called on the class itself, not on an existing date, because their job is to create one.
How do I format a date in Python?
Call strftime(), short for string format time, on a date or datetime with a pattern of format codes. Each code starts with % and stands for one part of the date, such as %Y for the four-digit year.
from datetime import datetime
meeting = datetime(2026, 10, 28, 14, 30)
print(meeting.strftime("%Y-%m-%d"))
print(meeting.strftime("%d/%m/%Y %H:%M"))
print(meeting.strftime("%A, %B %d, %Y"))
print(meeting.strftime("%I:%M %p"))2026-10-28 28/10/2026 14:30 Wednesday, October 28, 2026 02:30 PM
Anything in the pattern that isn't a code, like a slash or a comma, is copied as it is. The same codes work after the colon in an f-string, so f"{meeting:%d %b %Y}" gives 28 Oct 2026.
In strftime(), %d is the day of the month, not the %d number placeholder from the string formatting lesson.
| Code | Meaning | For 2026-10-28 14:30 |
|---|---|---|
%Y | Year with four digits | 2026 |
%y | Year with two digits | 26 |
%m | Month as two digits | 10 |
%B | Month name | October |
%b | Short month name | Oct |
%d | Day of the month as two digits | 28 |
%A | Weekday name | Wednesday |
%a | Short weekday name | Wed |
%H | Hour from 00 to 23 | 14 |
%I | Hour from 01 to 12 | 02 |
%p | AM or PM | PM |
%M | Minute as two digits | 30 |
%S | Second as two digits | 00 |
%j | Day of the year as three digits | 301 |
Month and day names come out in English unless the program changes its locale, the language and region setting, with the locale module. The format codes table in the documentation lists the standard codes, and some systems support a few more.
How do I convert a string to a date in Python?
Use datetime.strptime(), short for string parse time, with the text and a pattern that matches it. For text in ISO 8601 form, such as 2026-12-25, date.fromisoformat() needs no pattern.
from datetime import date, datetime
meeting = datetime.strptime("28/10/2026 14:30", "%d/%m/%Y %H:%M")
print(meeting)
print(date.fromisoformat("2026-12-25"))
print(datetime.strptime("25 Dec 2026", "%d %b %Y").date())2026-10-28 14:30:00 2026-12-25 2026-12-25
The whole string has to match the pattern, or strptime() raises ValueError. Calling .date() drops the time from a datetime, and Python 3.14 added date.strptime(), which gives the date in one call.
A pattern with a day but no year, as in "%b %d", gets a warning in Python 3.14 and an error in 3.15, because without a year Python can't tell whether February 29 exists. Put the year in both the text and the pattern.
How do I add or subtract days from a date in Python?
Add or subtract a timedelta, a length of time such as timedelta(days=7). Python handles month ends and leap years for you.
from datetime import date, timedelta
start = date(2026, 10, 28)
print(start + timedelta(days=7))
print(start - timedelta(weeks=2))
print(date(2026, 3, 1) - timedelta(days=1))2026-11-04 2026-10-14 2026-02-28
A timedelta takes weeks, days, hours, minutes, seconds, milliseconds and microseconds, but no months or years, because months and years differ in length.
To move by whole months, set the month with start.replace(month=11) and check the day exists in it, or install python-dateutil with pip and use its relativedelta.
How do I find the number of days between two dates in Python?
Subtract one date from the other and read .days from the result. The subtraction gives a timedelta, and its days attribute is a plain integer.
from datetime import date
start = date(2026, 10, 28)
christmas = date(2026, 12, 25)
gap = christmas - start
print(gap)
print(gap.days)
print(christmas > start)58 days, 0:00:00 58 True
Printing the timedelta itself shows the days and a time part, while .days gives a number you can compare and calculate with. Dates compare the way numbers do, so a later date is greater than an earlier one.
How do I get the day of the week in Python?
Call weekday(), which returns 0 for Monday through 6 for Sunday. isoweekday() counts from 1 for Monday to 7 for Sunday, and strftime("%A") gives the name.
from datetime import date
christmas = date(2026, 12, 25)
print(christmas.weekday())
print(christmas.isoweekday())
print(christmas.strftime("%A"))4 5 Friday
Christmas 2026 falls on a Friday, so weekday() gives 4 and isoweekday() gives 5. Mixing the two up shifts every day by one. Before you compare day numbers, check which method the code uses.
How do I work with time zones in Python?
Pass a time zone as tzinfo to get an aware datetime, one that knows its offset from UTC. UTC, or Coordinated Universal Time, is the reference clock that time zones are measured from.
A datetime without a time zone is called naive. Methods that need an offset, such as timestamp() and astimezone(), treat a naive datetime as the computer's local time.
from datetime import datetime, timedelta, timezone
meeting = datetime(2026, 10, 28, 14, 30, tzinfo=timezone.utc)
india = timezone(timedelta(hours=5, minutes=30))
print(meeting)
print(meeting.astimezone(india))2026-10-28 14:30:00+00:00 2026-10-28 20:00:00+05:30
astimezone() converts an aware datetime to another zone. India keeps the same +05:30 offset all year, so a fixed timezone object is right for it, while zones with daylight saving time need the zoneinfo module.
zoneinfo uses the IANA time zone database, the shared record of every region's offsets and clock changes.
from datetime import datetime
from zoneinfo import ZoneInfo
meeting = datetime(2026, 10, 28, 14, 30, tzinfo=ZoneInfo("Europe/London"))
print(meeting.astimezone(ZoneInfo("America/New_York")))
Code that uses zoneinfo has to run on your own computer, because the runner can read your clock but has no data for named zones such as Europe/London. The installing Python lesson shows how to set up Python. On Windows, python -m pip install tzdata adds the zone data.
On your computer, the London-to-New York conversion prints 2026-10-28 10:30:00-04:00. New York is usually five hours behind London, but that week the gap is four hours, because UK daylight saving time ends on October 25, 2026 and New York's ends on November 1.
The time zone converter shows a time in other named zones, with no code.
What is a Unix timestamp in Python?
A Unix timestamp is the number of seconds since January 1, 1970, in UTC. timestamp() turns a datetime into one, and datetime.fromtimestamp() turns one back.
from datetime import datetime, timezone
new_year = datetime(2026, 1, 1, tzinfo=timezone.utc)
print(new_year.timestamp())
print(datetime.fromtimestamp(0, tz=timezone.utc))1767225600.0 1970-01-01 00:00:00+00:00
Pass tz=timezone.utc to fromtimestamp() to get UTC, because without it the result is in the local time zone. time.time() from the time module returns the current timestamp.
To read any timestamp as a date, paste it into the Unix timestamp converter.
Common mistakes with dates in Python
Three of these four mistakes with Python dates raise an error, but the first one doesn't.
- %M instead of %m.
%Mis the minute and%mis the month, so"%Y-%M-%d"prints the minutes where the month should be, with no error. Check%Yagainst%yand%Hagainst%Ithe same way. - TypeError: can't compare offset-naive and offset-aware datetimes. One side has a time zone and the other doesn't. Give both a time zone, or neither.
- ValueError: day 30 must be in range 1..28 for month 2 in year 2026.
date(2026, 2, 30)asked for a day that doesn't exist. Check values that come from user input before building a date. - AttributeError: module 'datetime' has no attribute 'now'. After
import datetime, the namedatetimeis the module and the class isdatetime.datetime. Calldatetime.datetime.now(), or import the class withfrom datetime import datetime. Python 3.15 adds a hint that suggests the first fix.
The program below uses %M for the month by mistake. Change it to %m and run it again.
from datetime import datetime
meeting = datetime(2026, 10, 28, 14, 5)
print(meeting.strftime("%Y-%M-%d"))2026-05-28
Exercise
Turn start into a date with date.fromisoformat(), so adding 30 days works and the program prints 27 November 2026. The starter stops with a TypeError, because start is still a string.
from datetime import date, timedelta
start = "2026-10-28"
due = start + timedelta(days=30)
print(due.strftime("%d %B %Y"))
27 November 2026
Show the solution
from datetime import date, timedelta
start = date.fromisoformat("2026-10-28")
due = start + timedelta(days=30)
print(due.strftime("%d %B %Y"))
Quiz
This quiz has 5 questions. Pick an answer to see why it is right or wrong.
-
1What does this program print?
from datetime import date, timedelta print(date(2026, 3, 1) - timedelta(days=1))2026 is not a leap year, so the day before March 1 is February 28. timedelta follows the real calendar, and a date never has day 0.
-
2What does this program print?
from datetime import datetime print(datetime(2026, 10, 28, 9, 5).strftime("%d/%M/%Y"))%M is the minute, which is 5 here and prints as 05. The month code is the lowercase %m, which would have printed 10.
-
3What is the difference between date.today() and datetime.now()?
Both read the local clock, so neither one uses UTC. date.today() returns a date object such as 2026-10-28 with no time part at all, and datetime.now() returns a datetime that also holds the hour, minute, second and microsecond.
-
4What does this program print?
from datetime import date print((date(2026, 12, 25) - date(2026, 12, 1)).days)Subtracting two dates counts the days from one to the other, so December 1 to December 2 is 1 day, and December 1 to December 25 is 24, not 25. The days attribute gives that count as a plain number, while printing the timedelta itself would show 24 days, 0:00:00.
-
5Which method turns the string "2026-12-25" into a date object?
fromisoformat() parses text in ISO 8601 form, such as 2026-12-25. fromtimestamp() builds a date from a number of seconds, and isoformat() and strftime() go the other way, from a date to text.























