Python Dates

Master date and time manipulation in Python using the datetime module

šŸ“… Working with Dates

Python does not have a built-in data type for dates, but you can import the datetime module to work with dates and times. This module provides classes for working with dates and times in both simple and complex ways.


# Import datetime module
from datetime import datetime, date, time

# Get current date and time
current = datetime.now()      # Full datetime
today = date.today()         # Just date
now = datetime.now().time()  # Just time

# Create specific date
birthday = date(1990, 1, 15)  # Year, month, day
                                    
datetime
Module
Flexible
Formatting
Powerful
Operations

The datetime Module

The datetime module provides classes for working with dates and times. The most commonly used class is datetime itself.

šŸ“…

datetime

Main class for date and time operations

šŸ“†

date

For working with dates only

ā°

time

For working with times only

ā±ļø

timedelta

For time differences and arithmetic

Getting the Current Date and Time

To get the current date and time, you can use the now() method of the datetime class.

current_datetime.py
import datetime

# Get current date and time
now = datetime.datetime.now()
print("Current date and time:", now)

# Get current date only
today = datetime.date.today()
print("Current date:", today)

# Get current time only
current_time = datetime.datetime.now().time()
print("Current time:", current_time)

Expected Output:

Current date and time: 2024-01-15 14:30:45.123456
Current date: 2024-01-15
Current time: 14:30:45.123456

Creating Date Objects

To create a date object, you can use the datetime() class constructor. It requires three parameters: year, month, and day. Other parameters like hour, minute, second, and microsecond are optional.

create_dates.py
import datetime

# Create a date object for a specific date
date1 = datetime.datetime(2024, 5, 17)
print("Date 1:", date1)

# Create a date object with time
date2 = datetime.datetime(2023, 12, 25, 10, 30, 45)
print("Date 2:", date2)

# Create using date class (date only)
birthday = datetime.date(1990, 6, 15)
print("Birthday:", birthday)

# Create using time class (time only)
meeting_time = datetime.time(14, 30, 0)
print("Meeting time:", meeting_time)

# Create a timedelta (duration)
duration = datetime.timedelta(days=7, hours=3, minutes=30)
print("Duration:", duration)

Formatting Dates (strftime())

The datetime object has a method for formatting date objects into readable strings. This method is called strftime(), and it takes one parameter, format, to specify the format of the returned string.

šŸ“‹ Common Format Codes:

%Y 4-digit year (2024)
%y 2-digit year (24)
%m Month as number (01-12)
%B Full month name (January)
%b Short month name (Jan)
%d Day of month (01-31)
%A Full weekday name (Monday)
%a Short weekday name (Mon)
%H Hour 24-hour format (00-23)
%I Hour 12-hour format (01-12)
%M Minute (00-59)
%S Second (00-59)
%p AM or PM
%j Day of year (001-366)
date_formatting.py
import datetime

now = datetime.datetime.now()

print("Date Formatting Examples:")
print("=" * 40)

# Basic formats
print(f"ISO format: {now.strftime('%Y-%m-%d')}")
print(f"US format: {now.strftime('%m/%d/%Y')}")
print(f"European format: {now.strftime('%d/%m/%Y')}")

# Full date formats
print(f"Full date: {now.strftime('%A, %B %d, %Y')}")
print(f"Short date: {now.strftime('%a, %b %d, %Y')}")

# Time formats
print(f"24-hour time: {now.strftime('%H:%M:%S')}")
print(f"12-hour time: {now.strftime('%I:%M %p')}")

# Combined formats
print(f"Full datetime: {now.strftime('%A, %B %d, %Y at %I:%M %p')}")
print(f"Compact: {now.strftime('%Y%m%d_%H%M%S')}")

# Special formats
print(f"Day of year: {now.strftime('%j')}")
print(f"Week number: {now.strftime('%U')}")

# Custom formats
print(f"Custom 1: {now.strftime('Today is %A, the %d of %B, %Y')}")
print(f"Custom 2: {now.strftime('Time: %I:%M %p on %m/%d/%Y')}")

Date Arithmetic

You can perform arithmetic operations on dates using timedelta objects to add or subtract time periods.

date_arithmetic.py
import datetime

# Current date and time
now = datetime.datetime.now()
print(f"Current date: {now.strftime('%Y-%m-%d %H:%M:%S')}")

# Add time periods
one_week_later = now + datetime.timedelta(weeks=1)
print(f"One week later: {one_week_later.strftime('%Y-%m-%d %H:%M:%S')}")

one_month_later = now + datetime.timedelta(days=30)
print(f"30 days later: {one_month_later.strftime('%Y-%m-%d %H:%M:%S')}")

# Subtract time periods
yesterday = now - datetime.timedelta(days=1)
print(f"Yesterday: {yesterday.strftime('%Y-%m-%d %H:%M:%S')}")

# Calculate age
birth_date = datetime.date(1990, 6, 15)
today = datetime.date.today()
age = today - birth_date
print(f"Age in days: {age.days}")
print(f"Age in years: {age.days // 365}")

# Calculate time until event
new_year = datetime.datetime(2025, 1, 1)
time_until_new_year = new_year - now
print(f"Days until New Year: {time_until_new_year.days}")

# Working hours calculation
start_work = datetime.datetime(2024, 1, 15, 9, 0, 0)  # 9 AM
end_work = datetime.datetime(2024, 1, 15, 17, 30, 0)  # 5:30 PM
work_duration = end_work - start_work
print(f"Work duration: {work_duration}")
print(f"Work hours: {work_duration.total_seconds() / 3600:.1f} hours")

Parsing Date Strings

You can convert date strings into datetime objects using the strptime() method.

parse_dates.py
import datetime

# Parse different date string formats
date_strings = [
    "2024-01-15",
    "01/15/2024",
    "January 15, 2024",
    "15-Jan-2024",
    "2024-01-15 14:30:00"
]

formats = [
    "%Y-%m-%d",
    "%m/%d/%Y", 
    "%B %d, %Y",
    "%d-%b-%Y",
    "%Y-%m-%d %H:%M:%S"
]

print("Parsing Date Strings:")
print("=" * 30)

for date_str, fmt in zip(date_strings, formats):
    try:
        parsed_date = datetime.datetime.strptime(date_str, fmt)
        print(f"'{date_str}' → {parsed_date}")
    except ValueError as e:
        print(f"Error parsing '{date_str}': {e}")

# Practical example: Parse user input
def parse_user_date(date_input):
    """Try to parse a date string in multiple formats"""
    common_formats = [
        "%Y-%m-%d",
        "%m/%d/%Y",
        "%d/%m/%Y", 
        "%B %d, %Y",
        "%b %d, %Y",
        "%d-%b-%Y"
    ]
    
    for fmt in common_formats:
        try:
            return datetime.datetime.strptime(date_input, fmt)
        except ValueError:
            continue
    
    raise ValueError(f"Unable to parse date: {date_input}")

# Test the function
test_dates = ["2024-12-25", "12/25/2024", "December 25, 2024"]
for test_date in test_dates:
    try:
        result = parse_user_date(test_date)
        print(f"Successfully parsed '{test_date}': {result.strftime('%A, %B %d, %Y')}")
    except ValueError as e:
        print(e)

Real-World Example: Event Scheduler

Let's create a practical example that demonstrates various date operations in a real-world scenario.

event_scheduler.py
import datetime

class EventScheduler:
    def __init__(self):
        self.events = []
    
    def add_event(self, name, date_str, time_str):
        """Add an event to the scheduler"""
        try:
            # Parse date and time
            event_datetime = datetime.datetime.strptime(
                f"{date_str} {time_str}", "%Y-%m-%d %H:%M"
            )
            
            event = {
                'name': name,
                'datetime': event_datetime,
                'created': datetime.datetime.now()
            }
            
            self.events.append(event)
            print(f"āœ… Event '{name}' scheduled for {event_datetime.strftime('%A, %B %d, %Y at %I:%M %p')}")
            
        except ValueError as e:
            print(f"āŒ Error scheduling event: {e}")
    
    def get_upcoming_events(self, days=7):
        """Get events in the next N days"""
        now = datetime.datetime.now()
        future_limit = now + datetime.timedelta(days=days)
        
        upcoming = []
        for event in self.events:
            if now <= event['datetime'] <= future_limit:
                upcoming.append(event)
        
        # Sort by date
        upcoming.sort(key=lambda x: x['datetime'])
        return upcoming
    
    def get_overdue_events(self):
        """Get events that have passed"""
        now = datetime.datetime.now()
        overdue = [event for event in self.events if event['datetime'] < now]
        return overdue
    
    def time_until_event(self, event_name):
        """Calculate time until a specific event"""
        now = datetime.datetime.now()
        
        for event in self.events:
            if event['name'].lower() == event_name.lower():
                if event['datetime'] > now:
                    time_diff = event['datetime'] - now
                    days = time_diff.days
                    hours, remainder = divmod(time_diff.seconds, 3600)
                    minutes, _ = divmod(remainder, 60)
                    
                    return f"{days} days, {hours} hours, {minutes} minutes"
                else:
                    return "Event has already passed"
        
        return "Event not found"
    
    def display_schedule(self):
        """Display all events in a formatted way"""
        if not self.events:
            print("šŸ“… No events scheduled")
            return
        
        print("šŸ“… EVENT SCHEDULE")
        print("=" * 50)
        
        # Sort events by date
        sorted_events = sorted(self.events, key=lambda x: x['datetime'])
        
        for event in sorted_events:
            event_date = event['datetime']
            now = datetime.datetime.now()
            
            # Determine status
            if event_date < now:
                status = "šŸ”“ PAST"
            elif event_date.date() == now.date():
                status = "🟔 TODAY"
            else:
                status = "🟢 UPCOMING"
            
            print(f"{status} | {event['name']}")
            print(f"     šŸ“… {event_date.strftime('%A, %B %d, %Y')}")
            print(f"     ā° {event_date.strftime('%I:%M %p')}")
            print(f"     šŸ“ Added: {event['created'].strftime('%m/%d/%Y %I:%M %p')}")
            print()

# Example usage
scheduler = EventScheduler()

# Add some events
scheduler.add_event("Team Meeting", "2024-01-20", "10:00")
scheduler.add_event("Project Deadline", "2024-01-25", "17:00")
scheduler.add_event("Birthday Party", "2024-01-18", "19:00")
scheduler.add_event("Doctor Appointment", "2024-01-22", "14:30")

print("\n" + "="*50)
scheduler.display_schedule()

print("\n" + "="*50)
print("šŸ“‹ UPCOMING EVENTS (Next 7 days):")
upcoming = scheduler.get_upcoming_events(7)
for event in upcoming:
    days_until = (event['datetime'] - datetime.datetime.now()).days
    print(f"• {event['name']} - {event['datetime'].strftime('%m/%d at %I:%M %p')} ({days_until} days)")

print("\n" + "="*50)
print("ā° TIME UNTIL EVENTS:")
for event_name in ["Team Meeting", "Project Deadline", "Birthday Party"]:
    time_left = scheduler.time_until_event(event_name)
    print(f"• {event_name}: {time_left}")

# Calculate business days
def calculate_business_days(start_date, end_date):
    """Calculate number of business days between two dates"""
    current = start_date
    business_days = 0
    
    while current <= end_date:
        # Monday = 0, Sunday = 6
        if current.weekday() < 5:  # Monday to Friday
            business_days += 1
        current += datetime.timedelta(days=1)
    
    return business_days

# Example: Calculate business days until project deadline
today = datetime.date.today()
deadline = datetime.date(2024, 1, 25)
biz_days = calculate_business_days(today, deadline)
print(f"\nšŸ“Š Business days until project deadline: {biz_days}")

# Age calculator
def calculate_age(birth_date):
    """Calculate exact age in years, months, and days"""
    today = datetime.date.today()
    
    years = today.year - birth_date.year
    months = today.month - birth_date.month
    days = today.day - birth_date.day
    
    if days < 0:
        months -= 1
        # Get days in previous month
        if today.month == 1:
            prev_month = datetime.date(today.year - 1, 12, 1)
        else:
            prev_month = datetime.date(today.year, today.month - 1, 1)
        
        next_month = datetime.date(today.year, today.month, 1)
        days_in_prev_month = (next_month - prev_month).days
        days += days_in_prev_month
    
    if months < 0:
        years -= 1
        months += 12
    
    return years, months, days

# Example usage
birth_date = datetime.date(1990, 6, 15)
years, months, days = calculate_age(birth_date)
print(f"\nšŸŽ‚ Age: {years} years, {months} months, {days} days")

🧠 Test Your Knowledge

Which method is used to get the current date and time in Python?

What does the strftime() method do?

Which format code represents a 4-digit year?