Python • Python-Specific Topics

datetime Module — Use datetime for date/time basics (intro)

Learn how Python's datetime module lets you create, manipulate, and format dates and times in your programs.

Code braces with terminal and markup symbols representing Python programming.
Inside this lesson 10 sections 5 questions 5 figures

SECTION 1

Historical Context & Motivation

Computers have needed to track dates and times since their earliest days. When you log into a website, send a text message, or schedule a reminder, the software behind the scenes is storing and comparing timestamps. Before standardized libraries existed, programmers had to write their own date-handling code from scratch — accounting for leap years, time zones, and the varying number of days in each month. This led to countless bugs and even famous disasters like the Y2K bug, where storing years as two digits threatened to cause widespread computer failures at the turn of the millennium.

Python's datetime module was introduced as part of the standard library to give every Python programmer a reliable, well-tested toolkit for working with dates and times. Instead of reinventing the wheel, you can import a single module and immediately start creating date objects, calculating time differences, and formatting dates for display.

1970 • Unix Epoch Established

The Unix operating system begins counting time from January 1, 1970 (midnight UTC). This epoch becomes the universal reference point for computer timestamps.

1989 • Python Created by Guido van Rossum

Python's first version includes the time module for basic time functions, but it relies on low-level C functions and lacks intuitive date objects.

2000 • Y2K Bug Highlights Date Handling Risks

The global Y2K scare demonstrates how critical robust date handling is. Programmers around the world realize that standardized, well-tested date libraries are essential.

2002 • datetime Module Added to Python 2.3

Python introduces the datetime module, providing object-oriented classes for dates, times, and time deltas. It becomes the standard way to handle dates in Python.

2020s • datetime Remains the Standard

The datetime module continues to be Python's go-to tool for date and time operations. Third-party libraries like dateutil and arrow build on top of it for advanced features.

The central question the datetime module answers is simple but important: How do we represent, manipulate, and display dates and times in a way that is both accurate and easy for programmers to use? In this lesson, you will learn the core classes in the datetime module and how to put them to work in your own programs.

SECTION 2

Core Principles & Key Classes

The datetime module is built around a handful of classes, each designed to represent a different aspect of time. Understanding these classes is the foundation for everything you will do with dates in Python. You always begin by importing the module with from datetime import date, datetime, timedelta (or similar import statements), and then you create objects from these classes.

1

date

Represents a calendar date with year, month, and day attributes. Use it when you only care about the calendar date, not the specific time. Created with date(2025, 1, 15).
2

time

Represents a time of day with hour, minute, second, and microsecond, independent of any particular date. Created with time(14, 30, 0).
3

datetime

Combines both a date and a time into a single object. This is the most commonly used class. Created with datetime(2025, 1, 15, 14, 30).
4

timedelta

Represents a duration — the difference between two dates or times. Use it to add or subtract time. Created with timedelta(days=7) for a one-week span.
✦

KEY TAKEAWAY

Think of the datetime module like a calendar on your wall and a clock on your desk. The date class is the calendar page (just the date), the time class is the clock face (just the time), the datetime class is both combined into one, and timedelta is like counting the number of days between two dates you circled on the calendar.

SECTION 3

Visual Explanation — The datetime Class Hierarchy

datetime Module — Key Classesdatetime moduledate.year .month .daydate(2025, 1, 15)→ 2025-01-15time.hour .minute .secondtime(14, 30, 0)→ 14:30:00timedelta.days .secondstimedelta(days=7)→ 7 days, 0:00:00datetimeCombines date + time in one object.year .month .day .hour .minute .seconddatetime(2025, 1, 15, 14, 30) → 2025-01-15 14:30:00Dashed lines show that datetime combines the functionality of date and timetimedelta measures the gap between any two date or datetime objects
This diagram shows the four main classes in the datetime module. The datetime class (gold box) combines the attributes of both date (cyan) and time (pink), while timedelta (green) represents durations between two points in time.

As you can see in the diagram above, the datetime class sits at the intersection of date and time. This means a single datetime object carries all six attributes — year, month, day, hour, minute, and second — making it the most versatile class for everyday use. The timedelta class stands alongside them as the tool for measuring and calculating differences in time.

SECTION 4

How It Works — Creating and Using datetime Objects

Working with the datetime module follows a consistent pattern: you import the classes you need, create objects, and then access their attributes or call their methods. Let's walk through the key operations one by one.

Importing and Creating Objects

The module is named datetime, and it contains a class also called datetime. This can be confusing at first! The most common import style is from datetime import date, datetime, timedelta so you can use the class names directly. To create a specific date, you pass the year, month, and day as arguments: my_date = date(2025, 6, 15). For a full date and time, use my_dt = datetime(2025, 6, 15, 9, 30, 0) where the last three numbers are hour, minute, and second.

Getting the Current Date and Time

One of the most useful features is grabbing the current date and time. The method datetime.now() returns a datetime object representing the exact moment the code runs. Similarly, date.today() returns just today's date without any time information.

Accessing Attributes

Once you have a datetime or date object, you can access its parts using dot notation. For example, if now = datetime.now(), then now.year gives the year, now.month gives the month (1–12), now.day gives the day, and now.hour gives the hour in 24-hour format.

Formatting with strftime()

The strftime() method (short for 'string format time') converts a datetime object into a formatted string. You pass a format string using special codes: %Y for a four-digit year, %m for a two-digit month, %d for the day, %H for the hour (24-hour), and %M for the minute. For example, now.strftime("%B %d, %Y") might produce "January 15, 2025".

Arithmetic with timedelta

You can add or subtract timedelta objects to shift dates forward or backward. Writing date.today() + timedelta(days=30) gives you the date 30 days from now. You can also subtract two date or datetime objects to get a timedelta: difference = date2 - date1 and then access difference.days to see how many days apart they are.

SECTION 5

strftime Format Codes — Detailed Breakdown

The strftime() method is incredibly flexible. The table below lists the most commonly used format codes you will encounter. Each code starts with a percent sign and is replaced by the corresponding date/time component when the string is generated.

CodeMeaningExample Output
%YFour-digit year2025
%mMonth as zero-padded number (01–12)01
%dDay as zero-padded number (01–31)15
%HHour in 24-hour format (00–23)14
%IHour in 12-hour format (01–12)02
%MMinute (00–59)30
%SSecond (00–59)00
%BFull month nameJanuary
%AFull weekday nameWednesday
%pAM or PMPM

Common strftime format codes for the datetime module

How strftime() Builds a Formatted StringInput datetime object:datetime(2025, 1, 15, 14, 30, 0)Format string:"%B %d, %Y at %I:%M %p"Each code gets replaced with its value:%BJanuary%d15%Y2025%I02%M30%pPMOutput string:"January 15, 2025 at 02:30 PM"
This diagram shows how strftime() takes a datetime object and a format string, then substitutes each format code (like %B and %Y) with the corresponding value to produce a human-readable string.

Notice that literal characters like the comma, spaces, and the word "at" in the format string are passed through unchanged. Only codes starting with % are replaced. This gives you full control over how dates appear to your users — whether you want "01/15/2025" (American format), "15/01/2025" (European format), or something completely custom.

SECTION 6

Worked Example — Building a Countdown Timer

Let's write a short program that calculates how many days remain until a specific event — for instance, the last day of school on June 6, 2025. This example uses multiple datetime concepts together.

Countdown to Last Day of School

  1. 1

    Step 1 — Import the needed classes

    We need date for working with calendar dates and timedelta is returned automatically when we subtract dates. Write: from datetime import date
    from datetime import date
  2. 2

    Step 2 — Get today's date

    The class method date.today() returns the current date from the system clock. Store it in a variable: today = date.today(). If today is January 15, 2025, this creates date(2025, 1, 15).
    today = date.today() # date(2025, 1, 15)
  3. 3

    Step 3 — Create the target date

    Construct the last day of school as a date object. Remember the arguments are (year, month, day): last_day = date(2025, 6, 6).
    last_day = date(2025, 6, 6)
  4. 4

    Step 4 — Subtract to get the difference

    When you subtract one date from another, Python returns a timedelta object. We write: remaining = last_day - today. The result is a timedelta representing 142 days.
    remaining = last_day - today # timedelta(days=142)
  5. 5

    Step 5 — Display the result

    Access the .days attribute of the timedelta to get an integer. We can use an f-string for a nice display: print(f"Only {remaining.days} days until the last day of school!")
    Output: Only 142 days until the last day of school!
💡

Complete Code

from datetime import date today = date.today() last_day = date(2025, 6, 6) remaining = last_day - today print(f"Only {remaining.days} days until the last day of school!")

SECTION 7

Strengths, Limitations & Comparisons

The datetime module is powerful, but it is important to understand both what it does well and where it falls short. Knowing its limitations helps you pick the right tool for the job.

FeatureStrengthsLimitations
Date ArithmeticEasy addition and subtraction with timedelta; automatically handles month lengths and leap yearsNo built-in way to add months or years (only days, seconds, and weeks)
Formattingstrftime() supports many format codes and works consistently across platformsFormat codes can be tricky to memorize (%m vs %M); no natural language parsing built in
Time ZonesSupports timezone-aware datetimes via the tzinfo interfaceBuilt-in timezone support is minimal; most developers need the third-party pytz or zoneinfo library
Built-inPart of Python's standard library — no installation requiredLess user-friendly than third-party alternatives like arrow or pendulum
ComparisonDatetime objects support <, >, ==, and other comparison operators directlyCannot compare naive (no timezone) and aware (has timezone) datetimes; raises TypeError

Strengths and limitations of Python's datetime module

✦

KEY TAKEAWAY

Think of the datetime module as a reliable Swiss Army knife for dates and times. It handles most common tasks easily, but for specialized jobs like converting between world time zones or parsing dates from messy user input, you may want to reach for a more specialized tool (like the zoneinfo module or the dateutil library).

SECTION 8

Connection to Advanced Topics

The basics you have learned here form the foundation for more advanced date and time handling. As your projects grow in complexity, you will encounter situations where you need features beyond what we have covered today. The table below previews how introductory datetime concepts connect to more advanced topics.

Intro Concept (This Lesson)Advanced Concept (Future Learning)
date.today() and datetime.now()Timezone-aware datetime.now(tz=ZoneInfo('US/Eastern')) using the zoneinfo module
strftime() for formatting outputstrptime() for parsing date strings into datetime objects (the reverse operation)
timedelta(days=7) for simple offsetsThe dateutil.relativedelta for adding months and years accurately
Comparing two dates with < and >Sorting lists of datetime objects and using them as dictionary keys or database timestamps
Accessing .year, .month, .dayUsing .isoformat(), .weekday(), .isocalendar() for ISO standards and calendar operations

How introductory datetime concepts connect to advanced topics

As you move into web development, data science, or app building, you will find that datetime is used almost everywhere. Database records are timestamped with datetime values. APIs send dates as ISO 8601 strings (like "2025-01-15T14:30:00Z") that you will parse using strptime(). Mastering the basics now gives you a strong foundation for all of these future applications.

SECTION 9

Practice Problems

Question 1: CONCEPTUAL

What is the difference between a date object and a datetime object in Python's datetime module? When would you choose one over the other?
Show answer
A date object stores only the calendar date (year, month, and day), while a datetime object stores both the date and the time (year, month, day, hour, minute, second, and microsecond). You would choose date when time information is irrelevant — for example, recording a birthday or a homework due date. You would use datetime when the specific time matters, such as logging when a user submitted a form or scheduling a meeting.

Question 2: BASIC CALCULATION

Write a Python expression that creates a date object for March 14, 2025 (Pi Day). Then write another expression that uses strftime() to format it as "03/14/2025".
Show answer
First, import and create the date: from datetime import date followed by pi_day = date(2025, 3, 14). Then format it: pi_day.strftime("%m/%d/%Y") returns "03/14/2025". The code %m gives the zero-padded month, %d gives the zero-padded day, and %Y gives the four-digit year.

Question 3: INTERMEDIATE

A library book was checked out on January 10, 2025, and is due in 21 days. Write code that calculates the due date using timedelta and prints it in the format "Friday, January 31, 2025".
Show answer
Import the necessary classes: from datetime import date, timedelta. Create the checkout date: checkout = date(2025, 1, 10). Add 21 days: due_date = checkout + timedelta(days=21), which gives date(2025, 1, 31). Format and print it: print(due_date.strftime("%A, %B %d, %Y")) outputs "Friday, January 31, 2025". The %A code provides the full weekday name, which Python computes automatically.

Question 4: APPLIED

You are building a simple age calculator. Given a birthdate of September 5, 2007, write code that calculates the person's age in complete years as of today. Hint: you can subtract dates and use the .days attribute, then divide by 365.
Show answer
Start with: from datetime import date. Then: birth = date(2007, 9, 5) and today = date.today(). Calculate the difference: age_days = (today - birth).days. For an approximate age in years: age_years = age_days // 365. If today is January 15, 2025, then age_days is 6,341 and age_years is 17. Note that dividing by 365 is approximate because leap years add extra days. For production code, you would compare the month and day directly, but this approach is good enough for a quick calculation.

Question 5: CRITICAL THINKING

A student writes the following code and is surprised by the output: from datetime import datetime dt = datetime(2025, 3, 1) - datetime(2025, 2, 1) print(dt.days) They expected 30 but got 28. Explain why, and describe how the result would change if the year were 2024 instead of 2025.
Show answer
The code subtracts February 1 from March 1, which means it calculates the number of days in February. In 2025, February has 28 days because 2025 is not a leap year. Therefore dt.days returns 28, not 30. If the year were changed to 2024, which is a leap year (divisible by 4 and not a century year exception), February would have 29 days, and the output would be 29. This illustrates an important point: the datetime module automatically accounts for varying month lengths and leap years in its arithmetic. The student's assumption that all months have 30 days is the source of their confusion. Always let datetime handle the math rather than assuming fixed month lengths.

SUMMARY

Lesson Summary

Summary

Python's datetime module provides four core classes for handling dates and times. The date class represents a calendar date (year, month, day), the time class represents a time of day, the datetime class combines both into one object, and timedelta represents a duration between two points in time. You create objects by passing numeric arguments (like year, month, and day), and you can retrieve the current date or time using date.today() or datetime.now().

To display dates in a specific format, use the strftime() method with format codes like %Y (year), %m (month), and %d (day). To perform date arithmetic, add or subtract timedelta objects, or subtract two dates to get a timedelta. The module handles tricky details like leap years and varying month lengths automatically, making it an essential part of every Python programmer's toolkit.

Varsity Tutors • Python • datetime Module — Use datetime for date/time basics (intro)