← 返回首页 | ← 返回教程列表

Python学习教程 - 第十课:日期和时间处理,掌控时间的魔法!

欢迎回来!🎉 这节课我们要学习如何处理日期和时间——在实际编程中经常用到的重要技能!


复习一下前九节课

前九节课我们学会了: - 变量和基本数据类型 - 条件判断和循环 - 列表和字典 - 函数(代码的魔法师) - 文件操作(数据持久化) - 模块和包(代码组织) - 面向对象编程(OOP) - 异常和错误处理 - 正则表达式

这节课我们要学习如何处理日期和时间!


第一个知识点:datetime模块

导入datetime模块

import datetime
from datetime import datetime, date, time, timedelta

获取当前时间

# 当前日期和时间
now = datetime.now()
print("当前时间:", now)
print("年:", now.year)
print("月:", now.month)
print("日:", now.day)
print("时:", now.hour)
print("分:", now.minute)
print("秒:", now.second)
print("微秒:", now.microsecond)

# 当前日期
today = date.today()
print("\n当前日期:", today)
print("年:", today.year)
print("月:", today.month)
print("日:", today.day)

# 星期几
print("\n星期(0=周一, 6=周日):", now.weekday())
print("星期(1=周一, 7=周日):", now.isoweekday())

第二个知识点:创建日期和时间对象

创建date对象

# 创建指定日期
d = date(2024, 3, 15)
print("指定日期:", d)

# 从时间戳创建
timestamp = 1710451200  # 2024-03-15
d_from_timestamp = date.fromtimestamp(timestamp)
print("从时间戳创建:", d_from_timestamp)

# 从ISO格式字符串创建
d_from_iso = date.fromisoformat("2024-03-15")
print("从ISO字符串创建:", d_from_iso)

创建time对象

# 创建指定时间
t = time(14, 30, 45)
print("指定时间:", t)
print("时:", t.hour)
print("分:", t.minute)
print("秒:", t.second)
print("微秒:", t.microsecond)

# 从ISO格式字符串创建
t_from_iso = time.fromisoformat("14:30:45")
print("从ISO字符串创建:", t_from_iso)

创建datetime对象

# 创建指定日期时间
dt = datetime(2024, 3, 15, 14, 30, 45)
print("指定日期时间:", dt)

# 合并date和time
d = date(2024, 3, 15)
t = time(14, 30, 45)
dt_combined = datetime.combine(d, t)
print("合并日期和时间:", dt_combined)

# 从时间戳创建
dt_from_timestamp = datetime.fromtimestamp(1710451200)
print("从时间戳创建:", dt_from_timestamp)

# 从ISO格式字符串创建
dt_from_iso = datetime.fromisoformat("2024-03-15T14:30:45")
print("从ISO字符串创建:", dt_from_iso)

第三个知识点:日期时间格式化

strftime():格式化为字符串

now = datetime.now()

# 常用格式
print("默认格式:", now)
print("YYYY-MM-DD:", now.strftime("%Y-%m-%d"))
print("YYYY年MM月DD日:", now.strftime("%Y年%m月%d日"))
print("HH:MM:SS:", now.strftime("%H:%M:%S"))
print("完整格式:", now.strftime("%Y-%m-%d %H:%M:%S"))
print("星期:", now.strftime("%A"))
print("月份:", now.strftime("%B"))
print("12小时制:", now.strftime("%Y-%m-%d %I:%M:%S %p"))

# 格式码说明
"""
%Y  4位年份 (2024)
%y  2位年份 (24)
%m  月份 (01-12)
%B  月份全名 (March)
%b  月份缩写 (Mar)
%d  日期 (01-31)
%A  星期全名 (Friday)
%a  星期缩写 (Fri)
%H  24小时制 (00-23)
%I  12小时制 (01-12)
%M  分钟 (00-59)
%S  秒 (00-59)
%p  AM/PM
%f  微秒
%z  时区偏移
"""

# 中文格式化
weekday_names = ["星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期日"]
month_names = ["", "一月", "二月", "三月", "四月", "五月", "六月", 
               "七月", "八月", "九月", "十月", "十一月", "十二月"]

print(f"\n中文格式: {now.year}{month_names[now.month]}{now.day}{weekday_names[now.weekday()]}")

strptime():从字符串解析

# 解析日期时间字符串
date_str = "2024-03-15 14:30:45"
dt = datetime.strptime(date_str, "%Y-%m-%d %H:%M:%S")
print("解析结果:", dt)

# 不同格式的解析
date_str1 = "2024年03月15日"
dt1 = datetime.strptime(date_str1, "%Y年%m月%d日")
print("解析中文日期:", dt1)

date_str2 = "03/15/2024 2:30 PM"
dt2 = datetime.strptime(date_str2, "%m/%d/%Y %I:%M %p")
print("解析美式日期:", dt2)

第四个知识点:时间差计算(timedelta)

创建timedelta对象

# 创建时间差
delta1 = timedelta(days=7)
delta2 = timedelta(weeks=2)
delta3 = timedelta(hours=3, minutes=30)
delta4 = timedelta(days=1, hours=2, minutes=30, seconds=45)

print("7天:", delta1)
print("2周:", delta2)
print("3小时30分:", delta3)
print("混合:", delta4)

# 时间差的属性
print("\ndays:", delta4.days)
print("seconds:", delta4.seconds)
print("total_seconds():", delta4.total_seconds())

日期时间加减

now = datetime.now()

print("当前时间:", now)

# 加法
print("\n1天后:", now + timedelta(days=1))
print("1周后:", now + timedelta(weeks=1))
print("3小时后:", now + timedelta(hours=3))
print("30分钟后:", now + timedelta(minutes=30))

# 减法
print("\n1天前:", now - timedelta(days=1))
print("1周前:", now - timedelta(weeks=1))
print("3小时前:", now - timedelta(hours=3))

# 日期相减
d1 = date(2024, 3, 15)
d2 = date(2024, 3, 1)
delta = d1 - d2
print(f"\n{d1} - {d2} = {delta.days}天")

# 时间相减
t1 = datetime(2024, 3, 15, 14, 30)
t2 = datetime(2024, 3, 15, 10, 0)
delta = t1 - t2
print(f"{t1} - {t2} = {delta}")
print(f"总秒数: {delta.total_seconds()}")

第五个知识点:常用日期计算

计算年龄

def calculate_age(birth_date):
    """计算年龄"""
    today = date.today()
    age = today.year - birth_date.year

    # 如果今年生日还没过,减1岁
    if (today.month, today.day) < (birth_date.month, birth_date.day):
        age -= 1

    return age

# 测试
birth_date = date(2000, 5, 15)
age = calculate_age(birth_date)
print(f"出生日期: {birth_date}")
print(f"年龄: {age}岁")

判断闰年

def is_leap_year(year):
    """判断是否是闰年"""
    # 能被4整除但不能被100整除,或者能被400整除
    return year % 4 == 0 and (year % 100 != 0 or year % 400 == 0)

# 测试
years = [2000, 2004, 1900, 2023, 2024]
for year in years:
    print(f"{year}年是闰年吗?{is_leap_year(year)}")

计算两个日期之间的天数

def days_between(date1, date2):
    """计算两个日期之间的天数"""
    delta = date2 - date1
    return abs(delta.days)

# 测试
d1 = date(2024, 1, 1)
d2 = date(2024, 12, 31)
print(f"{d1}{d2}{days_between(d1, d2)} 天")

获取某个月的天数

def days_in_month(year, month):
    """获取某个月的天数"""
    if month == 12:
        next_month = date(year + 1, 1, 1)
    else:
        next_month = date(year, month + 1, 1)

    first_day = date(year, month, 1)
    return (next_month - first_day).days

# 测试
print("2024年2月有", days_in_month(2024, 2), "天")
print("2023年2月有", days_in_month(2023, 2), "天")
print("2024年4月有", days_in_month(2024, 4), "天")

获取某个日期所在周的周一和周日

def get_week_range(date_obj):
    """获取日期所在周的周一和周日"""
    # weekday()返回0=周一, 6=周日
    start = date_obj - timedelta(days=date_obj.weekday())
    end = start + timedelta(days=6)
    return start, end

# 测试
today = date.today()
monday, sunday = get_week_range(today)
print(f"本周: {monday}{sunday}")

第六个知识点:time模块

时间戳

import time

# 当前时间戳(秒)
timestamp = time.time()
print("当前时间戳(秒):", timestamp)

# 时间戳(毫秒)
timestamp_ms = int(time.time() * 1000)
print("当前时间戳(毫秒):", timestamp_ms)

# 时间戳转datetime
dt = datetime.fromtimestamp(timestamp)
print("时间戳转datetime:", dt)

# datetime转时间戳
dt = datetime.now()
timestamp = dt.timestamp()
print("datetime转时间戳:", timestamp)

程序休眠

import time

print("开始...")
time.sleep(2)  # 休眠2秒
print("2秒后...")
time.sleep(0.5)  # 休眠0.5秒
print("0.5秒后...")

计时

import time

# 方法1:使用time.time()
start = time.time()
# 执行一些操作
time.sleep(1)
end = time.time()
print(f"耗时: {end - start:.2f}秒")

# 方法2:使用time.perf_counter()(更精确)
start = time.perf_counter()
time.sleep(1)
end = time.perf_counter()
print(f"耗时: {end - start:.2f}秒")

# 方法3:使用装饰器
def timer(func):
    def wrapper(*args, **kwargs):
        start = time.perf_counter()
        result = func(*args, **kwargs)
        end = time.perf_counter()
        print(f"{func.__name__} 耗时: {end - start:.4f}秒")
        return result
    return wrapper

@timer
def slow_function():
    time.sleep(0.5)
    return "完成"

slow_function()

第七个知识点:calendar模块

日历相关操作

import calendar

# 设置每周的第一天(0=周一, 6=周日)
calendar.setfirstweekday(calendar.MONDAY)

# 打印某个月的日历
print("2024年3月的日历:")
print(calendar.month(2024, 3))

# 打印整年的日历
print("\n2024年的日历:")
print(calendar.calendar(2024))

# 判断是否是闰年
print("\n2024是闰年吗?", calendar.isleap(2024))
print("2023是闰年吗?", calendar.isleap(2023))

# 某个月的第一天是星期几,有多少天
weekday, num_days = calendar.monthrange(2024, 3)
print(f"\n2024年3月: 第一天是星期{weekday}(0=周一),共{num_days}天")

# 某个月的日历矩阵
print("\n2024年3月的日历矩阵:")
print(calendar.monthcalendar(2024, 3))

综合练习:日程管理系统

让我们创建一个实用的日程管理系统!

from datetime import datetime, date, timedelta
import json
from pathlib import Path

class Event:
    """事件类"""
    def __init__(self, title, start_time, end_time=None, description=""):
        self.title = title
        self.start_time = start_time
        self.end_time = end_time or start_time + timedelta(hours=1)
        self.description = description
        self.created_at = datetime.now()

    def to_dict(self):
        """转换为字典"""
        return {
            'title': self.title,
            'start_time': self.start_time.isoformat(),
            'end_time': self.end_time.isoformat(),
            'description': self.description,
            'created_at': self.created_at.isoformat()
        }

    @classmethod
    def from_dict(cls, data):
        """从字典创建"""
        event = cls(
            title=data['title'],
            start_time=datetime.fromisoformat(data['start_time']),
            end_time=datetime.fromisoformat(data['end_time']),
            description=data.get('description', '')
        )
        event.created_at = datetime.fromisoformat(data['created_at'])
        return event

    def __str__(self):
        return f"📅 {self.start_time.strftime('%Y-%m-%d %H:%M')} - {self.end_time.strftime('%H:%M')} | {self.title}"

class ScheduleManager:
    """日程管理器"""
    def __init__(self, data_file="schedule.json"):
        self.data_file = Path(data_file)
        self.events = []
        self.load()

    def add_event(self, title, start_time, end_time=None, description=""):
        """添加事件"""
        event = Event(title, start_time, end_time, description)
        self.events.append(event)
        self.save()
        print(f"✅ 已添加事件: {title}")
        return event

    def delete_event(self, index):
        """删除事件"""
        if 0 <= index < len(self.events):
            event = self.events.pop(index)
            self.save()
            print(f"✅ 已删除事件: {event.title}")
        else:
            print("❌ 无效的索引")

    def get_events_by_date(self, target_date):
        """获取某一天的事件"""
        target_events = []
        for event in self.events:
            if event.start_time.date() == target_date:
                target_events.append(event)
        return sorted(target_events, key=lambda e: e.start_time)

    def get_upcoming_events(self, days=7):
        """获取未来几天的事件"""
        today = date.today()
        end_date = today + timedelta(days=days)

        upcoming = []
        for event in self.events:
            event_date = event.start_time.date()
            if today <= event_date <= end_date:
                upcoming.append(event)

        return sorted(upcoming, key=lambda e: e.start_time)

    def list_all_events(self):
        """列出所有事件"""
        if not self.events:
            print("当前没有事件")
            return

        print("\n" + "="*60)
        print("  📅 所有事件")
        print("="*60)
        for i, event in enumerate(sorted(self.events, key=lambda e: e.start_time)):
            print(f"{i+1}. {event}")
            if event.description:
                print(f"   描述: {event.description}")
        print("="*60 + "\n")

    def show_today_schedule(self):
        """显示今天的日程"""
        today = date.today()
        events = self.get_events_by_date(today)

        print(f"\n📅 {today.strftime('%Y年%m月%d日')} 的日程:")
        if not events:
            print("  今天没有安排")
        else:
            for event in events:
                print(f"  • {event.start_time.strftime('%H:%M')} - {event.title}")
        print()

    def show_reminders(self):
        """显示提醒(即将发生的事件)"""
        now = datetime.now()
        one_hour_later = now + timedelta(hours=1)

        reminders = []
        for event in self.events:
            if now <= event.start_time <= one_hour_later:
                reminders.append(event)

        if reminders:
            print("\n🔔 即将开始的事件:")
            for event in reminders:
                minutes_to_start = int((event.start_time - now).total_seconds() / 60)
                print(f"  • {event.title} - {minutes_to_start}分钟后开始")
            print()

    def save(self):
        """保存到文件"""
        data = [event.to_dict() for event in self.events]
        with open(self.data_file, 'w', encoding='utf-8') as f:
            json.dump(data, f, ensure_ascii=False, indent=2)

    def load(self):
        """从文件加载"""
        if self.data_file.exists():
            with open(self.data_file, 'r', encoding='utf-8') as f:
                data = json.load(f)
                self.events = [Event.from_dict(event_data) for event_data in data]

# 演示日程管理系统
def main():
    print("="*60)
    print("  📅 日程管理系统")
    print("="*60)

    manager = ScheduleManager()

    # 添加一些示例事件
    now = datetime.now()

    manager.add_event(
        title="团队会议",
        start_time=datetime(now.year, now.month, now.day, 10, 0),
        end_time=datetime(now.year, now.month, now.day, 11, 0),
        description="讨论项目进度"
    )

    manager.add_event(
        title="午餐",
        start_time=datetime(now.year, now.month, now.day, 12, 0),
        end_time=datetime(now.year, now.month, now.day, 13, 0)
    )

    manager.add_event(
        title="代码评审",
        start_time=datetime(now.year, now.month, now.day, 14, 30),
        description="评审新功能代码"
    )

    # 明天的事件
    tomorrow = date.today() + timedelta(days=1)
    manager.add_event(
        title="客户拜访",
        start_time=datetime(tomorrow.year, tomorrow.month, tomorrow.day, 9, 0),
        end_time=datetime(tomorrow.year, tomorrow.month, tomorrow.day, 11, 0),
        description="拜访重要客户"
    )

    # 显示今天的日程
    manager.show_today_schedule()

    # 显示即将开始的事件
    manager.show_reminders()

    # 显示未来7天的事件
    print("\n📆 未来7天的事件:")
    upcoming = manager.get_upcoming_events(7)
    for event in upcoming:
        print(f"  • {event}")

    # 列出所有事件
    manager.list_all_events()

if __name__ == "__main__":
    main()

第十课小结

今天我们学会了:

datetime模块:处理日期和时间的核心模块
创建日期时间对象:date、time、datetime
格式化:strftime()和strptime()
时间差计算:timedelta
常用日期计算:年龄、闰年、天数等
time模块:时间戳、计时、休眠
calendar模块:日历相关操作
实战项目:日程管理系统


课后练习 ✏️

  1. 写一个函数,计算两个日期之间相差多少个工作日(排除周末)
  2. 写一个函数,生成某个月的所有周一
  3. 写一个倒计时程序,显示距离某个目标日期还有多少天
  4. 写一个简单的时钟程序,每秒更新一次时间
  5. 写一个程序,统计某个日期范围内有多少个周末

下节课预告:我们会学习网络编程,如何进行HTTP请求和API调用!

继续加油!你已经掌握了Python编程的核心技能!💪