Python Dates

Learn how to work with dates and times in Python using the datetime module.

Python Dates

A date in Python is not a data type of its own, but we can import a module named datetime to work with dates as date objects.

Example - Import the datetime module and display the current date:

import datetime

x = datetime.datetime.now()
print(x)

Date Output

When we executed the code from the example above the result was:

2023-12-07 14:30:59.123456

The date contains year, month, day, hour, minute, second, and microsecond.

The datetime module has many methods to return information about the date object.

Example - Return the year and name of weekday:

import datetime

x = datetime.datetime.now()

print(x.year)
print(x.strftime("%A"))

Creating Date Objects

To create a date, we can use the datetime() class (constructor) of the datetime module.

The datetime() class requires three parameters to create a date: year, month, day.

Example - Create a date object:

import datetime

x = datetime.datetime(2020, 5, 17)

print(x)

The datetime() class also takes parameters for time and timezone (hour, minute, second, microsecond, tzone), but they are optional, and has a default value of 0, (None for timezone).

The strftime() Method

The datetime object has a method for formatting date objects into readable strings.

The method is called strftime(), and takes one parameter, format, to specify the format of the returned string:

Example - Display the name of the month:

import datetime

x = datetime.datetime(2018, 6, 1)

print(x.strftime("%B"))

Format Codes

A reference of all the legal format codes:

%a
Weekday, short version
Wed
%A
Weekday, full version
Wednesday
%w
Weekday as a number 0-6, 0 is Sunday
3
%d
Day of month 01-31
31
%b
Month name, short version
Dec
%B
Month name, full version
December
%m
Month as a number 01-12
12
%y
Year, short version, without century
18
%Y
Year, full version
2018
%H
Hour 00-23
17
%I
Hour 00-12
05
%p
AM/PM
PM
%M
Minute 00-59
41
%S
Second 00-59
08
%f
Microsecond 000000-999999
548513
%z
UTC offset
+0100
%Z
Timezone
CST
%j
Day number of year 001-366
365
%U
Week number of year, Sunday as the first day of week, 00-53
52
%W
Week number of year, Monday as the first day of week, 00-53
52
%c
Local version of date and time
Mon Dec 31 17:41:00 2018
%x
Local version of date
12/31/18
%X
Local version of time
17:41:00
%%
A % character
%

Working with Different Date Components

Date Only

import datetime

# Create date only
today = datetime.date.today()
print(today)  # 2023-12-07

# Create specific date
birthday = datetime.date(1990, 5, 15)
print(birthday)  # 1990-05-15

# Access date components
print(f"Year: {today.year}")
print(f"Month: {today.month}")
print(f"Day: {today.day}")
print(f"Weekday: {today.weekday()}")  # Monday is 0

Time Only

import datetime

# Create time only
current_time = datetime.time(14, 30, 45)
print(current_time)  # 14:30:45

# With microseconds
precise_time = datetime.time(14, 30, 45, 123456)
print(precise_time)  # 14:30:45.123456

# Access time components
print(f"Hour: {current_time.hour}")
print(f"Minute: {current_time.minute}")
print(f"Second: {current_time.second}")

DateTime Combined

import datetime

# Current date and time
now = datetime.datetime.now()
print(now)

# Specific date and time
event = datetime.datetime(2023, 12, 25, 18, 30, 0)
print(event)

# Combine date and time objects
date_part = datetime.date(2023, 12, 25)
time_part = datetime.time(18, 30, 0)
combined = datetime.datetime.combine(date_part, time_part)
print(combined)

Date Arithmetic

You can perform arithmetic operations on dates using timedelta:

Example - Date arithmetic:

import datetime

# Current date
today = datetime.date.today()
print(f"Today: {today}")

# Add days
future_date = today + datetime.timedelta(days=30)
print(f"30 days from now: {future_date}")

# Subtract days
past_date = today - datetime.timedelta(days=7)
print(f"7 days ago: {past_date}")

# Add weeks
next_week = today + datetime.timedelta(weeks=1)
print(f"Next week: {next_week}")

# Complex timedelta
complex_delta = datetime.timedelta(
    days=7,
    hours=3,
    minutes=30,
    seconds=45
)
future_datetime = datetime.datetime.now() + complex_delta
print(f"Future datetime: {future_datetime}")

# Calculate difference between dates
date1 = datetime.date(2023, 1, 1)
date2 = datetime.date(2023, 12, 31)
difference = date2 - date1
print(f"Days between: {difference.days}")
print(f"Total seconds: {difference.total_seconds()}")

Parsing Dates from Strings

Convert string representations to datetime objects:

Example - Parse dates from strings:

import datetime

# Parse common date formats
date_str1 = "2023-12-07"
parsed_date1 = datetime.datetime.strptime(date_str1, "%Y-%m-%d")
print(parsed_date1)

date_str2 = "December 7, 2023"
parsed_date2 = datetime.datetime.strptime(date_str2, "%B %d, %Y")
print(parsed_date2)

date_str3 = "07/12/2023 14:30:45"
parsed_date3 = datetime.datetime.strptime(date_str3, "%d/%m/%Y %H:%M:%S")
print(parsed_date3)

# Handle different formats
date_formats = [
    "%Y-%m-%d",
    "%d/%m/%Y",
    "%m-%d-%Y",
    "%B %d, %Y"
]

date_string = "12-07-2023"
for fmt in date_formats:
    try:
        parsed = datetime.datetime.strptime(date_string, fmt)
        print(f"Successfully parsed with format {fmt}: {parsed}")
        break
    except ValueError:
        continue
else:
    print("Could not parse date string")

Working with Timezones

Handle timezone-aware datetime objects:

Example - Timezone handling:

import datetime
import pytz  # pip install pytz

# Create timezone-aware datetime
utc = pytz.UTC
eastern = pytz.timezone('US/Eastern')
pacific = pytz.timezone('US/Pacific')

# Current time in UTC
utc_now = datetime.datetime.now(utc)
print(f"UTC: {utc_now}")

# Convert to different timezones
eastern_time = utc_now.astimezone(eastern)
pacific_time = utc_now.astimezone(pacific)

print(f"Eastern: {eastern_time}")
print(f"Pacific: {pacific_time}")

# Create timezone-aware datetime directly
eastern_dt = eastern.localize(datetime.datetime(2023, 12, 7, 14, 30))
print(f"Eastern datetime: {eastern_dt}")

# Convert between timezones
pacific_dt = eastern_dt.astimezone(pacific)
print(f"Same time in Pacific: {pacific_dt}")

Practical Examples

Age Calculator

import datetime

def calculate_age(birth_date):
    """Calculate age in years from birth date."""
    today = datetime.date.today()
    age = today.year - birth_date.year
    
    # Check if birthday has occurred this year
    if today < birth_date.replace(year=today.year):
        age -= 1
    
    return age

# Example usage
birth_date = datetime.date(1990, 5, 15)
age = calculate_age(birth_date)
print(f"Age: {age} years")

# Days until next birthday
def days_until_birthday(birth_date):
    today = datetime.date.today()
    next_birthday = birth_date.replace(year=today.year)
    
    if next_birthday < today:
        next_birthday = birth_date.replace(year=today.year + 1)
    
    return (next_birthday - today).days

days = days_until_birthday(birth_date)
print(f"Days until next birthday: {days}")

Business Days Calculator

import datetime

def add_business_days(start_date, business_days):
    """Add business days to a date (excluding weekends)."""
    current_date = start_date
    days_added = 0
    
    while days_added < business_days:
        current_date += datetime.timedelta(days=1)
        # Monday is 0, Sunday is 6
        if current_date.weekday() < 5:  # Monday to Friday
            days_added += 1
    
    return current_date

def count_business_days(start_date, end_date):
    """Count business days between two dates."""
    current_date = start_date
    business_days = 0
    
    while current_date <= end_date:
        if current_date.weekday() < 5:
            business_days += 1
        current_date += datetime.timedelta(days=1)
    
    return business_days

# Example usage
start = datetime.date(2023, 12, 1)
end_date = add_business_days(start, 10)
print(f"10 business days from {start}: {end_date}")

business_day_count = count_business_days(start, end_date)
print(f"Business days between dates: {business_day_count}")

Event Scheduler

import datetime

class Event:
    def __init__(self, name, start_time, duration_minutes):
        self.name = name
        self.start_time = start_time
        self.duration = datetime.timedelta(minutes=duration_minutes)
        self.end_time = start_time + self.duration
    
    def __str__(self):
        return f"{self.name}: {self.start_time.strftime('%Y-%m-%d %H:%M')} - {self.end_time.strftime('%H:%M')}"
    
    def conflicts_with(self, other_event):
        """Check if this event conflicts with another event."""
        return (self.start_time < other_event.end_time and 
                self.end_time > other_event.start_time)
    
    def time_until_event(self):
        """Get time until event starts."""
        now = datetime.datetime.now()
        if now < self.start_time:
            return self.start_time - now
        return None

# Example usage
meeting1 = Event("Team Meeting", 
                 datetime.datetime(2023, 12, 7, 14, 0), 60)
meeting2 = Event("Client Call", 
                 datetime.datetime(2023, 12, 7, 14, 30), 30)

print(meeting1)
print(meeting2)
print(f"Conflicts: {meeting1.conflicts_with(meeting2)}")

time_until = meeting1.time_until_event()
if time_until:
    print(f"Time until meeting: {time_until}")