datetime 模块通关攻略:10 个逆天场景 + 30 道送命题,通关解锁时间掌控者称号

datetime 模块通关攻略:10 个逆天场景 + 30 道送命题,通关解锁时间掌控者称号

内容简介

本系列文章是为 Python3 学习者精心设计的一套全面、实用的学习指南,旨在帮助读者从基础入门到项目实战,全面提升编程能力。文章结构由 5 个版块组成,内容层层递进,逻辑清晰。

  1. 基础速通n 个浓缩提炼的核心知识点,夯实编程基础;
  2. 经典范例10 个贴近实际的应用场景,深入理解 Python3 的编程技巧和应用方法;
  3. 避坑宝典10 个典型错误解析,提供解决方案,帮助读者避免常见的编程陷阱;
  4. 水平考试10 道测试题目,检验学习成果,附有标准答案,以便自我评估;
  5. 实战案例3 个迷你项目开发,带领读者从需求分析到代码实现,掌握项目开发的完整流程。

无论你是 Python3 初学者,还是希望提升实战能力的开发者,本系列文章都能为你提供清晰的学习路径和实用的编程技巧,助你快速成长为 Python3 编程高手。


阅读建议

  • 初学者:建议从 “基础速通” 开始,系统学习 Python3 的基础知识,然后通过 “经典范例”“避坑宝典” 加深理解,最后通过 “水平考试”“实战案例” 巩固所学内容;
  • 有经验的开发者:可以直接跳转到 “经典范例”“避坑宝典”,快速掌握 Python3 的高级应用技巧和常见错误处理方法,然后通过 “实战案例” 提升项目开发能力;
  • 选择性学习:如果读者对某个特定主题感兴趣,可以直接选择相应版块学习。各版块内容既相互独立又逻辑关联,方便读者根据自身需求灵活选择;
  • 测试与巩固:完成每个版块的学习后,建议通过 “水平考试” 检验学习效果,并通过 “实战案例” 将理论知识转化为实际技能;
  • 项目实战优先:如果你更倾向于实战学习,可以直接从 “实战案例” 入手,边做边学,遇到问题再回溯相关知识点。

一、基础速通

Python 的 datetime 模块是标准库中用于处理日期和时间的核心模块。它提供了多种类和工具,方便开发者操作日期、时间、时间间隔以及时区信息。以下是其主要功能及组件:

1. 主要类及用途

1.1 datetime.date

  • 功能:处理日期(年、月、日)。
  • 示例
    from datetime import date
    today = date.today()  # 获取当前日期
    print(today)  # 输出格式:2023-10-05
    

1.2 datetime.time

  • 功能:处理时间(时、分、秒、微秒),不包含日期。
  • 示例
    from datetime import time
    t = time(14, 30, 15)  # 14点30分15秒
    print(t)  # 输出:14:30:15
    

1.3 datetime.datetime

  • 功能:同时处理日期和时间(最常用)。
  • 示例
    from datetime import datetime
    now = datetime.now()  # 当前日期和时间
    print(now)  # 输出:2023-10-05 14:30:15.123456
    

1.4 datetime.timedelta

  • 功能:表示时间间隔(如天数、秒数),用于日期/时间的加减运算。
  • 示例
    from datetime import datetime, timedelta
    now = datetime.now()
    tomorrow = now + timedelta(days=1)  # 当前时间加1天
    

1.5 datetime.tzinfo(抽象基类)

  • 功能:处理时区信息。需结合第三方库(如 pytz)实现具体时区操作。

2. 核心功能
2.1 日期/时间的创建与操作
from datetime import datetime, date

# 创建特定日期或时间
dt = datetime(2023, 10, 5, 14, 30)  # 2023年10月5日 14:30:00
d = date(2023, 10, 5)               # 仅日期

# 获取当前时间
current_time = datetime.now()
2.2 日期/时间的格式化与解析
  • 格式化输出(strftime:将日期时间转为字符串。
    formatted = dt.strftime("%Y-%m-%d %H:%M:%S")  # 输出:2023-10-05 14:30:00
    
  • 解析字符串(strptime:将字符串转为日期时间对象。
    parsed = datetime.strptime("2023-10-05", "%Y-%m-%d")
    
2.3 时间间隔计算
delta = timedelta(days=7, hours=3)
new_date = dt + delta  # 加7天3小时
2.4 时区处理
  • 默认 datetime 对象是“无时区”(naive),需借助 pytz 库处理时区:
    import pytz
    utc_time = datetime.now(pytz.utc)  # UTC时间
    local_time = utc_time.astimezone(pytz.timezone("Asia/Shanghai"))  # 转为上海时区
    
3. 小结内容

datetime 模块是 Python 处理日期和时间的标准工具,覆盖了从简单日期操作到复杂时区管理的需求。结合第三方库(如 pytzdateutil)可进一步扩展其功能。


二、经典范例

本节展示 10 个Python datetime 模块的经典应用范例,附带代码示例和详细解释。

1. 计算年龄(精确到天)

场景:根据出生日期计算用户的年龄(精确到天数)。

from datetime import date

def calculate_age(birth_date: date) -> tuple:
    today = date.today()
    years = today.year - birth_date.year
    months = today.month - birth_date.month
    days = today.day - birth_date.day

    # 调整未过生日的情况
    if (months < 0) or (months == 0 and days < 0):
        years -= 1
        months += 12

    # 计算剩余天数
    if days < 0:
        last_month = today.replace(month=today.month - 1)
        days_in_last_month = (today - last_month).days
        days += days_in_last_month
        months -= 1

    return years, months, days

birthday = date(1995, 8, 20)
age = calculate_age(birthday)
print(f"年龄:{age[0]}{age[1]}{age[2]}天")
# 输出示例:年龄:28岁 1月 15天

2. 时间戳与日期互转

场景:将 Unix 时间戳转换为可读日期,或反向操作。

from datetime import datetime

# 时间戳 -> 日期
timestamp = 1696521600  # 2023-10-05 00:00:00 UTC
dt = datetime.fromtimestamp(timestamp)
print(f"时间戳转日期:{dt.strftime('%Y-%m-%d %H:%M:%S')}")  # 输出:2023-10-05 00:00:00

# 日期 -> 时间戳
dt_obj = datetime(2023, 10, 5, 0, 0)
timestamp = int(dt_obj.timestamp())
print(f"日期转时间戳:{timestamp}")  # 输出:1696521600

3. 生成日期范围

场景:生成两个日期之间的所有日期列表。

from datetime import datetime, timedelta

def date_range(start: str, end: str) -> list:
    start_date = datetime.strptime(start, "%Y-%m-%d")
    end_date = datetime.strptime(end, "%Y-%m-%d")
    delta = end_date - start_date

    dates = []
    for i in range(delta.days + 1):
        current_date = start_date + timedelta(days=i)
        dates.append(current_date.strftime("%Y-%m-%d"))
    return dates

date_list = date_range("2023-10-01", "2023-10-05")
print(date_list)  # 输出:['2023-10-01', '2023-10-02', ..., '2023-10-05']

4. 判断闰年

场景:检查某年是否为闰年。

from datetime import date

def is_leap_year(year: int) -> bool:
    try:
        date(year, 2, 29)  # 尝试创建2月29日
        return True
    except ValueError:
        return False

print(is_leap_year(2024))  # 输出:True
print(is_leap_year(2023))  # 输出:False

5. 倒计时功能

场景:计算距离某个未来时间点的剩余时间。

from datetime import datetime, timedelta

def countdown(target: str) -> timedelta:
    now = datetime.now()
    target_time = datetime.strptime(target, "%Y-%m-%d %H:%M:%S")
    remaining = target_time - now
    return remaining

remaining_time = countdown("2024-01-01 00:00:00")
print(f"距离2024年元旦还有:{remaining_time.days}{remaining_time.seconds//3600}小时")

6. 统计代码执行时间

场景:测量某段代码的运行耗时。

from datetime import datetime

start = datetime.now()

# 模拟耗时操作
for _ in range(1000000):
    pass

end = datetime.now()
elapsed = end - start
print(f"代码执行耗时:{elapsed.total_seconds():.4f}秒")
# 输出示例:代码执行耗时:0.1234秒

7. 时区转换

场景:将本地时间转换为其他时区的时间。

from datetime import datetime
import pytz

# 本地时间 -> UTC时间
local_time = datetime.now()
utc_time = local_time.astimezone(pytz.utc)
print(f"UTC时间:{utc_time.strftime('%Y-%m-%d %H:%M:%S')}")

# UTC时间 -> 纽约时间
ny_tz = pytz.timezone("America/New_York")
ny_time = utc_time.astimezone(ny_tz)
print(f"纽约时间:{ny_time.strftime('%Y-%m-%d %H:%M:%S')}")

8. 获取月末日期

场景:计算某个月份的最后一天。

from datetime import date
import calendar

def last_day_of_month(year: int, month: int) -> date:
    _, last_day = calendar.monthrange(year, month)
    return date(year, month, last_day)

print(last_day_of_month(2023, 2))  # 输出:2023-02-28
print(last_day_of_month(2024, 2))  # 输出:2024-02-29

9. 解析 ISO 8601 格式日期

场景:处理符合国际标准的日期字符串。

from datetime import datetime

iso_date_str = "2023-10-05T14:30:45+08:00"
dt = datetime.fromisoformat(iso_date_str)
print(dt)  # 输出:2023-10-05 14:30:45+08:00

# 反向生成 ISO 格式
print(dt.isoformat())  # 输出原字符串

10. 时间差统计(精确到分钟)

场景:计算两个时间点之间的分钟数差值。

from datetime import datetime

def minutes_diff(start: str, end: str) -> int:
    fmt = "%Y-%m-%d %H:%M:%S"
    start_time = datetime.strptime(start, fmt)
    end_time = datetime.strptime(end, fmt)
    delta = end_time - start_time
    return delta.total_seconds() // 60

diff = minutes_diff("2023-10-05 09:30:00", "2023-10-05 11:45:00")
print(f"时间差:{diff} 分钟")  # 输出:135 分钟

小结内容
这些范例覆盖了 datetime 模块的常见需求:

  • 时间计算:年龄、倒计时、月末日期
  • 格式转换:时间戳、ISO 8601、时区
  • 实用工具:日期范围生成、闰年判断、代码计时
  • 业务逻辑:用户年龄验证、数据分析周期统计

通过组合这些方法,可以解决绝大多数日期时间处理问题。进阶场景可结合 dateutilpandas 库进一步扩展。


三、避坑宝典

本节介绍 10 种Python datetime 模块使用中的常见错误、原因分析及纠错方法,涵盖开发中高频踩坑场景。

1. 时区处理不当(Naive vs Aware 对象)
错误示例
from datetime import datetime
import pytz

# 错误:混合 naive 和 aware 对象
dt_utc = datetime.now(pytz.utc)  # aware(有时区)
dt_local = datetime.now()        # naive(无时区)
diff = dt_utc - dt_local         # 抛出 TypeError
原因
  • Naive 对象:无时区信息的时间对象(如默认的 datetime.now())。
  • Aware 对象:有时区信息的时间对象(如 datetime.now(pytz.utc))。
  • 直接混合运算会导致类型错误
纠错方法

统一时区处理:

dt_local = datetime.now(pytz.timezone("Asia/Shanghai"))  # 转为 aware
diff = dt_utc - dt_local  # 合法

2. 日期格式字符串混淆(如 %m 与 %M)
错误示例
from datetime import datetime

# 错误:将分钟格式符 %M 误写为月份 %m
dt = datetime.strptime("2023-10-05 14:30", "%Y-%m-%d %H:%m")
# 输出:datetime(2023, 10, 5, 14, 10)(错误解析)
原因
  • 格式符 %m 表示月份,%M 表示分钟。
  • 错误使用会导致解析结果混乱。
纠错方法

明确区分格式符:

dt = datetime.strptime("2023-10-05 14:30", "%Y-%m-%d %H:%M")  # 正确

3. 月份和天数顺序错误(如 2023-13-1)
错误示例
from datetime import datetime

# 错误:将日期字符串中的月和日顺序写反
dt = datetime.strptime("2023-13-05", "%Y-%d-%m")  # 误解析为 13月(不存在)
# 抛出 ValueError: month must be in 1..12
原因
  • 某些日期格式(如 %Y-%d-%m)容易混淆月和日的位置。
  • 输入数据不符合实际日期规则(如月份 >12)。
纠错方法
  • 统一使用 ISO 格式YYYY-MM-DD)解析:
    dt = datetime.strptime("2023-05-13", "%Y-%m-%d")  # 明确年月日顺序
    
  • 对用户输入做严格验证。

4. 未处理夏令时(DST)导致时间错误
错误示例
import pytz
from datetime import datetime

tz = pytz.timezone("America/New_York")
dt = datetime(2023, 3, 12, 2, 30)  # 夏令时切换时刻
dt_aware = tz.localize(dt)  # 可能抛出 AmbiguousTimeError 或 NonExistentTimeError
原因
  • 夏令时切换时,某些时间点不存在或重复(如时钟从 2:00 跳到 3:00)。
  • 直接创建时间对象可能导致歧义。
纠错方法

使用 localizeis_dst 参数处理歧义:

dt_aware = tz.localize(dt, is_dst=False)  # 明确指定是否为夏令时
# 或使用 normalize 调整
dt_aware = tz.normalize(dt_aware)

5. 日期越界(如 2月30日)
错误示例
from datetime import date

# 错误:创建不存在的日期
d = date(2023, 2, 30)  # 抛出 ValueError: day is out of range for month
原因
  • 未验证日期的有效性(如 2 月没有 30 天)。
纠错方法
  • 使用 calendar.monthrange 验证月份最大天数:
    import calendar
    
    year, month = 2023, 2
    max_day = calendar.monthrange(year, month)[1]
    if day > max_day:
        raise ValueError(f"{year}-{month} 最大天数为 {max_day}")
    

6. 时间差计算忽略负数(如过去时间减未来时间)
错误示例
from datetime import datetime

start = datetime(2023, 10, 5)
end = datetime(2023, 10, 1)
delta = end - start  # 结果为负时间差(timedelta(days=-4))
days = delta.days    # 输出 -4(可能导致后续逻辑错误)
原因
  • 未处理时间差为负数的情况,导致后续计算错误(如显示“剩余天数-4”)。
纠错方法

取绝对值或明确判断方向:

days = abs(delta.days)  # 输出 4
# 或检查方向
if delta.days < 0:
    print("时间已过期")

7. 误用 replace 方法修改时区
错误示例
import pytz
from datetime import datetime

dt_utc = datetime.now(pytz.utc)
dt_shanghai = dt_utc.replace(tzinfo=pytz.timezone("Asia/Shanghai"))  # 错误!
# 时区转换错误,时间数值未调整
原因
  • replace 仅修改时区信息,不转换时间数值(如 UTC+8 时区直接替换为 UTC 时区会错误)。
纠错方法

使用 astimezone 方法正确转换时区:

dt_shanghai = dt_utc.astimezone(pytz.timezone("Asia/Shanghai"))  # 正确

8. 字符串解析时未处理毫秒/微秒
错误示例
from datetime import datetime

dt_str = "2023-10-05 14:30:45.123456"
dt = datetime.strptime(dt_str, "%Y-%m-%d %H:%M:%S")  # 忽略微秒部分
# 抛出 ValueError: unconverted data remains: .123456
原因
  • 格式字符串未包含微秒占位符 %f
纠错方法

明确解析微秒:

dt = datetime.strptime(dt_str, "%Y-%m-%d %H:%M:%S.%f")  # 正确

9. 时间差计算单位混淆(如 days 与 total_seconds)
错误示例
from datetime import timedelta

delta = timedelta(days=1, hours=3)
total_hours = delta.days * 24 + delta.seconds // 3600  # 错误:结果为 24 + 3 = 27
# 正确方法应使用 total_seconds()
原因
  • timedelta.seconds 只包含不足1天的秒数(0~86399),days 是整数天数。
纠错方法

统一用 total_seconds() 计算总时间:

total_hours = delta.total_seconds() // 3600  # (86400 + 10800) / 3600 = 27

10. 忽略闰年影响日期计算
错误示例
from datetime import date, timedelta

# 错误:假设每年都是365天
d = date(2020, 2, 28)
next_year = d + timedelta(days=365)  # 2021-02-28(正确应为 2021-02-28)
# 但 2020 是闰年,实际应为 366 天
原因
  • 闰年(366 天)的存在影响跨年计算。
纠错方法

使用 dateutil.relativedelta 处理跨年:

from dateutil.relativedelta import relativedelta

next_year = d + relativedelta(years=1)  # 2021-02-28(自动处理闰年)

小结内容
错误类型关键点
时区混淆区分 naive/aware 对象,用 astimezone 转换时区
格式符误用熟记 strftime/strptime 格式符(如 %Y%m%d
夏令时和闰年使用 pytzdateutil 处理复杂时间逻辑
输入验证始终检查日期有效性(如月份 ≤12、天数 ≤31)
时间差计算优先用 total_seconds() 替代手动计算

避免这些错误的最佳实践:

  1. 始终明确时区,优先使用 aware 对象。
  2. 严格验证输入日期,避免越界。
  3. 使用第三方库(如 pytzdateutil)处理复杂逻辑。
  4. 编写单元测试覆盖边界条件(如闰年、夏令时)。

四、水平考试

为了测试 “Python datetime 模块” 的学习效果,请自行完成以下测试试卷。试卷共计30道试题,满分100。其中:选择题15题、填空题10题、编程题5题。每题后提供正确答案,供参考使用。


(一)选择题(每题2分,共30分)
  1. 以下哪个类用于处理“日期+时间”?
    A. datetime.date
    B. datetime.time
    C. datetime.datetime
    D. datetime.tzinfo
    答案:C

  2. strftime("%Y-%m-%d") 输出的格式是?
    A. 05-10-2023
    B. 2023/10/05
    C. 2023-10-05
    D. 10-05-2023
    答案:C

  3. 以下代码会抛出什么错误?

    from datetime import datetime  
    datetime.strptime("2023-13-01", "%Y-%m-%d")  
    

    A. TypeError
    B. ValueError
    C. KeyError
    D. 无错误
    答案:B

  4. datetime.timedelta 不能表示以下哪个时间单位?
    A. 天
    B. 小时
    C. 分钟
    D. 月
    答案:D

  5. 如何获取当前时间的 Unix 时间戳?
    A. datetime.now().timestamp()
    B. datetime.timestamp()
    C. datetime.now().time()
    D. datetime.utcnow()
    答案:A

  6. 以下哪个格式符表示“12小时制的小时”?
    A. %H
    B. %I
    C. %M
    D. %p
    答案:B

  7. datetime 对象转为时区无关的 UTC 时间,应使用哪个方法?
    A. replace(tzinfo=pytz.utc)
    B. astimezone(pytz.utc)
    C. datetime.utcnow()
    D. localize(pytz.utc)
    答案:B

  8. 以下代码的输出是?

    from datetime import timedelta  
    delta = timedelta(days=2, hours=3)  
    print(delta.total_seconds())  
    

    A. 183600
    B. 194400
    C. 180000
    D. 190800
    答案:D

  9. 判断闰年的正确方法是?
    A. 年份能被4整除
    B. 年份能被400整除,或能被4整除但不能被100整除
    C. 年份能被100整除
    D. 年份能被2整除
    答案:B

  10. 以下哪个方法用于解析字符串为 datetime 对象?
    A. strftime()
    B. fromisoformat()
    C. strptime()
    D. parse()
    答案:C

  11. 以下代码的输出是?

    from datetime import datetime  
    dt = datetime(2023, 10, 5, 14, 30)  
    print(dt.weekday())  # 2023-10-05 是星期四  
    

    A. 3
    B. 4
    C. 5
    D. 6
    答案:A

  12. datetime.now() 返回的对象是?
    A. Naive(无时区)
    B. Aware(有时区)
    C. 取决于系统设置
    D. 总是 UTC 时间
    答案:A

  13. 以下代码的功能是?

    from datetime import datetime  
    datetime.now().strftime("%Y-%m-%dT%H:%M:%SZ")  
    

    A. 生成 ISO 8601 格式字符串
    B. 生成带时区的时间字符串
    C. 生成 Unix 时间戳
    D. 解析时间字符串
    答案:A

  14. 计算两个日期相差的工作日天数,需要用到哪个模块?
    A. time
    B. calendar
    C. pytz
    D. dateutil
    答案:B 或 D(两种方法均可)

  15. 以下代码会抛出什么错误?

    from datetime import datetime  
    dt = datetime(2023, 2, 29)  
    

    A. TypeError
    B. ValueError
    C. KeyError
    D. 无错误
    答案:B


(二)填空题(每题3分,共30分)
  1. 获取当前日期和时间的代码是:datetime._________()
    答案:now

  2. 表示时间间隔的类是 _________
    答案:timedelta

  3. 将字符串 "2023-10-05" 解析为 date 对象的代码是:date._________("2023-10-05", "%Y-%m-%d")
    答案:strptime

  4. 计算 2023-02-28 加1天的结果是 _________
    答案:2023-03-01

  5. 判断 2024 年是否为闰年的代码:datetime(2024, 2, 29)._________()
    答案:无(直接创建成功即为闰年)

  6. datetime 对象转换为 ISO 8601 字符串的方法是 _________
    答案:isoformat()

  7. 获取某个月最后一天的代码需要用到 _________ 模块的 monthrange 函数。
    答案:calendar

  8. 创建一个表示“3小时30分钟”的 timedelta 对象:timedelta(hours=3, minutes=30)timedelta(seconds=_________ )
    答案:12600

  9. 将 UTC 时间转换为北京时间(东八区)的方法是 astimezone(_________)
    **答案:pytz.timezone(“Asia/Shanghai”)`

  10. 计算 datetime1datetime2 之间相差的总秒数的代码是:(datetime2 - datetime1)._________
    答案:total_seconds()


(三)编程题(每题8分,共40分)
  1. 编写函数,计算某人的出生天数。

    from datetime import date  
    
    def days_since_birth(birth_year, birth_month, birth_day):  
        today = date.today()  
        birth_date = date(birth_year, birth_month, birth_day)  
        delta = today - birth_date  
        return delta.days  
    
    print(days_since_birth(2000, 1, 1))  
    
  2. 编写代码,生成2023年12月的所有日期列表。

    from datetime import datetime, timedelta  
    
    start_date = datetime(2023, 12, 1)  
    dates = []  
    for i in range(31):  
        current_date = start_date + timedelta(days=i)  
        if current_date.month != 12:  
            break  
        dates.append(current_date.strftime("%Y-%m-%d"))  
    print(dates)  
    
  3. 将字符串 "2023-10-05 14:30:00+08:00" 转换为纽约时间(UTC-5)。

    import pytz  
    from datetime import datetime  
    
    dt_str = "2023-10-05 14:30:00+08:00"  
    dt = datetime.fromisoformat(dt_str)  
    ny_tz = pytz.timezone("America/New_York")  
    dt_ny = dt.astimezone(ny_tz)  
    print(dt_ny.strftime("%Y-%m-%d %H:%M:%S"))  
    
  4. 编写函数,判断两个日期是否在同一周(假设周一到周日为一周)。

    from datetime import datetime  
    
    def is_same_week(date1, date2):  
        week1 = date1.isocalendar()[1]  
        week2 = date2.isocalendar()[1]  
        return week1 == week2 and date1.year == date2.year  
    
    d1 = datetime(2023, 10, 2)  # 周一  
    d2 = datetime(2023, 10, 6)  # 周五  
    print(is_same_week(d1, d2))  # True  
    
  5. 编写代码,计算当前时间距离下一个元旦的剩余天数。

    from datetime import datetime  
    
    now = datetime.now()  
    next_year = now.year + 1  
    next_new_year = datetime(next_year, 1, 1)  
    delta = next_new_year - now  
    print(f"剩余天数:{delta.days} 天"))  
    

五、实战案例

本节内容展示 3 个 Python datetime 模块实战项目,提供了完整代码及详细解释。

项目1:智能工作日倒计时工具

目标:计算当天剩余的有效工作时间(例如 9:00-18:00,排除午休),适用于工作效率管理。

from datetime import datetime, timedelta

def work_time_remaining():
    now = datetime.now()
    today = now.date()
    work_start = datetime(today.year, today.month, today.day, 9, 0)   # 9:00 上班
    work_end = datetime(today.year, today.month, today.day, 18, 0)    # 18:00 下班
    lunch_start = datetime(today.year, today.month, today.day, 12, 0) # 12:00 午休
    lunch_end = datetime(today.year, today.month, today.day, 13, 30)  # 13:30 结束午休

    # 判断当前时间段
    if now < work_start:
        return "还未到工作时间!"
    elif now >= work_end:
        return "今天的工作时间已结束!"
    elif lunch_start <= now < lunch_end:
        remaining = (work_end - lunch_end).seconds // 60
        return f"午休中,剩余有效工作时间:{remaining} 分钟"
    else:
        if now < lunch_start:
            end = lunch_start
        else:
            end = work_end
        remaining = (end - now).seconds // 60
        return f"剩余有效工作时间:{remaining} 分钟"

# 测试案例
print(work_time_remaining())

执行结果示例(假设当前时间为 14:00):

剩余有效工作时间:240 分钟

项目2:生日倒计时与年龄计算

目标:输入生日,自动计算年龄及距离下次生日的天数,支持闰年。

from datetime import date

def birthday_countdown(birth_year, birth_month, birth_day):
    today = date.today()
    next_birthday = date(today.year, birth_month, birth_day)

    # 处理已过生日的情况
    if next_birthday < today:
        next_birthday = date(today.year + 1, birth_month, birth_day)

    # 计算年龄和剩余天数
    age = today.year - birth_year - ((today.month, today.day) < (birth_month, birth_day))
    days_left = (next_birthday - today).days

    return age, days_left

# 测试案例
age, days = birthday_countdown(2000, 2, 29)
print(f"年龄:{age}岁,距离下次生日还有:{days}天(自动处理闰年)")

执行结果示例(假设当前日期为 2023-10-05):

年龄:23岁,距离下次生日还有:147天(自动处理闰年)

项目3:考勤异常检测系统

目标:分析员工打卡记录,标记迟到(晚于9:15)、早退(早于18:00)和缺卡。

from datetime import datetime, time

def check_attendance(records: dict):
    # 定义考勤标准时间
    late_time = time(9, 15)
    early_leave_time = time(18, 0)

    result = {}
    for emp_id, times in records.items():
        status = []
        # 检查上午打卡
        if 'am' not in times:
            status.append("缺上午卡")
        else:
            am_time = datetime.strptime(times['am'], "%H:%M").time()
            if am_time > late_time:
                status.append(f"迟到 {am_time.strftime('%H:%M')}")

        # 检查下午打卡
        if 'pm' not in times:
            status.append("缺下午卡")
        else:
            pm_time = datetime.strptime(times['pm'], "%H:%M").time()
            if pm_time < early_leave_time:
                status.append(f"早退 {pm_time.strftime('%H:%M')}")

        result[emp_id] = "正常" if not status else " | ".join(status)
    return result

# 测试数据
records = {
    "001": {"am": "09:16", "pm": "17:59"},
    "002": {"am": "08:30", "pm": "18:30"},
    "003": {"am": "09:00"}
}
print(check_attendance(records))

执行结果

{
  '001': '迟到 09:16 | 早退 17:59', 
  '002': '正常', 
  '003': '缺下午卡'
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值