查看全课大纲(第 26 / 51 节)
  1. 1.为什么人人都该学点编程?
  2. 2.计算机与程序设计:你的电脑到底在“想”什么?
  3. 3.Python 这门语言,到底有什么魔力?
  4. 4.Python 开发环境配置:如何拥有你的第一个“编程工具箱”?
  5. 5.如何安装一个更强大的代码编辑器?
  6. 6.汇率兑换1.0:你的第一个“钱生钱”小程序
  7. 7.你的第一行代码,藏着哪些秘密?
  8. 8.汇率兑换2.0(上):让程序看懂“CNY”和“USD”
  9. 9.汇率兑换程序,如何让它“聪明”地判断币种?
  10. 10.汇率兑换程序能一直运行,直到我喊停吗?
  11. 11.汇率兑换4.0:如何把“算钱”功能打包成积木?
  12. 12.汇率兑换5.0:给你的程序穿上“结构化”的西装
  13. 13.怎么用 Python 画一个会动的五角星?
  14. 14.如何让程序自动画出不同大小的五角星?
  15. 15.函数自己调用自己,会发生什么?
  16. 16.用递归画出神奇的分形树
  17. 17.Python 怎么计算你一天躺着不动能消耗多少热量?
  18. 18.如何让程序“活”起来,持续为你服务?
  19. 19.如何让 BMR 计算器更“聪明”?
  20. 20.当程序遇到“不按套路出牌”的用户怎么办?
  21. 21.怎么用 Python 模拟一个“滚雪球”式的存钱计划?
  22. 22.如何用列表记录每一周的存款?
  23. 23.如何让程序自己数数?—— 用 for 循环解放你的双手
  24. 24.52周存钱挑战4.0:你的存款计算器能有多灵活?
  25. 25.52周存钱挑战:怎么根据日期自动查存款?
  26. 26.Python 怎么判断一年中的第几天?
  27. 27.列表 vs 元组:哪个更适合存储月份天数?
  28. 28.用集合给月份分个队,换个思路算天数
  29. 29.把月份和天数“锁”在一起:用字典给数据配个对
  30. 30.Python 怎么判断密码强弱?
  31. 31.Python 怎么给密码设置“防沉迷”系统?
  32. 32.Python 怎么把密码保存到文件里?
  33. 33.Python 怎么读取文件里的密码?
  34. 34.Python 怎么把密码检查工具“打包”起来?
  35. 35.Python 怎么把文件操作也“打包”起来?
  36. 36.计算机怎么“扔骰子”?——用Python模拟随机事件
  37. 37.如何用 Python 模拟掷两个骰子?
  38. 38.怎么用 Python 把骰子轨迹画出来?
  39. 39.骰子点数分布长啥样?用直方图一眼看穿!
  40. 40.用科学计算库让骰子程序“起飞”
  41. 41.空气质量指数怎么算?手把手教你写一个AQI计算器
  42. 42.空气质量指数计算:从零开始,让程序看懂空气
  43. 43.如何读取空气质量数据文件并找出空气质量最好的五个监测点?
  44. 44.JSON 数据怎么变成 Excel 表格?—— 让数据换个“马甲”
  45. 45.Python 怎么让程序自己判断文件类型?
  46. 46.如何让程序自己上网查空气质量?
  47. 47.用美味的汤来解析网页:Beautiful Soup 入门
  48. 48.如何让爬虫自动抓取全国所有城市的空气质量?
  49. 49.爬到的数据怎么存下来?—— 把全国空气质量数据保存为CSV文件
  50. 50.用 pandas 玩转空气质量数据:找出全国空气最好和最差的城市
  51. 51.空气质量数据怎么“洗”干净,还能画成图?

Python 怎么判断一年中的第几天?

约 22 分钟

小象实战讲义 · Python 入门:8 个小项目边玩边学

欢迎来到我们的第六个小项目!今天我们要玩一个“时间侦探”的游戏:给你一个具体的日期,比如你的生日,你能立刻说出这是那一年的第几天吗?是不是感觉有点难?别担心,学完这一节,你就能写一个超酷的“日期侦探”程序,让它帮你瞬间算出答案!

💡 核心导读

本节你将学到:

  • 新朋友:元组(tuple),一个“一旦创建就不能修改”的列表。
  • 核心算法:如何把“四年一闰,百年不闰,四百年再闰”的规则,变成计算机能理解的代码。
  • 项目迭代:从零开始,一步步构建出完整的“判断第几天”程序。
  • 本节只新增一个知识点:认识并使用元组来存储固定的月份天数。

一、项目启动:侦探需要什么线索?

我们的“日期侦探”程序要解决什么问题呢?很简单:输入一个具体的年月日,输出它是那一年的第几天。

听起来容易,但仔细一想,有两个“陷阱”:

  1. 月份天数不同:1月31天,2月28或29天,4月30天……不能简单相加。
  2. 闰年捣乱:2月的天数在闰年(29天)和平年(28天)不一样。

所以,我们的侦探需要两条核心线索:

  • 每个月的天数表(一个固定不变的数据)。
  • 闰年判断法则(一个清晰的逻辑规则)。

我们先来解决第二个问题,因为它是整个案件的“钥匙”。

二、破解闰年密码:把常识变成代码

闰年的规则大家可能听过:“四年一闰,百年不闰,四百年再闰”。怎么用程序表达呢?

我们把它拆解成计算机能懂的“条件语句”:

  1. 条件A(四百年再闰):年份能被400整除(年份 % 400 == 0)。
  2. 条件B(四年一闰且百年不闰):年份能被4整除 并且 不能被100整除((年份 % 4 == 0) and (年份 % 100 != 0))。

这两个条件满足任意一个,就是闰年。所以是“或”的关系。

举个例子:1900年。

  • 它能被4整除吗?能(1900 % 4 == 0)。
  • 它能被100整除吗?能(1900 % 100 == 0)。
  • 所以它不满足“百年不闰”的条件,因此1900年不是闰年。很多人的常识在这里会出错,但我们的程序不会!
# 闰年判断逻辑演示
year = 1900

# 条件A:能被400整除
condition_a = (year % 400 == 0)
# 条件B:能被4整除 且 不能被100整除
condition_b = (year % 4 == 0) and (year % 100 != 0)

is_leap_year = condition_a or condition_b

print(f"{year}年是闰年吗? {is_leap_year}")
1900年是闰年吗? False

看,程序完美地执行了规则。有了这把“钥匙”,我们就可以处理2月天数的问题了。

三、引入新工具:元组(tuple),一个“固执”的列表

现在我们需要一个地方来存放每个月的天数。之前我们学过列表(list),它可以存放一系列数据。今天我们来认识它的“表哥”——元组(tuple)。

它们最大的区别是:列表创建后可以随意修改(增删改),而元组一旦创建,里面的内容就不能修改了。就像一个刻在石头上的名单,无法擦写。

为什么用元组?因为一年的月份天数是固定的(1月永远是31天),我们不需要修改它,用元组更安全,也能提醒我们这是固定数据。

怎么创建和访问元组?

  • 创建:用圆括号 () 把数据括起来,数据之间用逗号隔开。
  • 访问:和列表一模一样,用中括号 [索引]。
# 对比列表和元组
# 1. 创建
my_list = [31, 28, 31]  # 列表,用方括号
my_tuple = (31, 28, 31) # 元组,用圆括号

print("列表:", my_list)
print("元组:", my_tuple)
print("它们的类型分别是:", type(my_list), type(my_tuple))

# 2. 访问(和列表一样)
print("元组的第一个元素:", my_tuple[0])

# 3. 尝试修改(看看会发生什么)
my_list[0] = 30  # 修改列表,完全OK
print("修改后的列表:", my_list)

# my_tuple[0] = 30 # 如果取消这行的注释,运行会报错!元组不能修改。
# print("修改后的元组:", my_tuple)
列表: [31, 28, 31]
元组: (31, 28, 31)
它们的类型分别是: <class 'list'> <class 'tuple'>
元组的第一个元素: 31
修改后的列表: [30, 28, 31]

看到了吗?当我们试图修改元组时,程序会报错。这种“固执”的特性,在存储像月份天数这种固定数据时,反而是个优点!

四、组装我们的“日期侦探”程序(1.0版)

万事俱备,我们来把线索和工具组装起来。本节新增的核心就是用元组来存储月份天数。

思路拆解:

  1. 获取输入:让用户输入一个日期,并把它解析成Python能处理的日期格式。
  2. 提取年月日:从日期中分离出年、月、日。
  3. 计算基础天数:
    • 用一个元组存储平年时每个月的天数。
    • 计算输入月份之前的所有月份的天数总和。
    • 加上输入日期中“日”的部分。
  4. 闰年修正:
    • 判断年份是否是闰年。
    • 如果是闰年 并且 月份大于2月(即已经过了2月),则在总天数上加1(因为2月是29天)。

下面是完整的1.0版程序:

# 判断第几天 1.0
# 使用元组(tuple)存储月份天数

# 导入datetime模块,用于处理日期
from datetime import datetime

# 1. 获取用户输入的日期
# 原程序使用 input(),这里为了你能直接运行,用一个固定日期代替
# 你可以将 `date_str` 的值改成任何你想测试的日期,格式必须是 `年/月/日`
date_str = '2012/03/05'  # 例如:2012年3月5日

# 2. 将字符串解析为真正的日期对象
input_date = datetime.strptime(date_str, '%Y/%m/%d')
print(f"你输入的日期是: {input_date}")

# 3. 从日期对象中提取年、月、日
year = input_date.year
month = input_date.month
day = input_date.day
print(f"解析得到:{year}年 {month}月 {day}日")

# 4. 使用元组存储平年各月的天数
# 注意:这里假设2月是28天(平年)
days_in_month_tup = (31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31)

# 5. 计算基础天数:之前月份的总天数 + 当月的天数
# days_in_month_tup[: month - 1] 表示获取从开始到(month-1)月份的所有天数
# 例如 month=3(三月),则取前两个月的天数 (31, 28)
days_before = sum(days_in_month_tup[: month - 1])
total_days = days_before + day
print(f"计算基础天数(按平年算): {days_before}(前几个月) + {day}(当日) = {total_days}天")

# 6. 闰年判断与修正
# 闰年规则:能被400整除 或 (能被4整除 且 不能被100整除)
if (year % 400 == 0) or ((year % 4 == 0) and (year % 100 != 0)):
    print(f"{year}年是闰年。")
    # 只有月份大于2月(即3月及以后),才需要补上加上的那一天
    if month > 2:
        total_days += 1
        print(f"因为月份 > 2,总天数加1,变为: {total_days}天")
else:
    print(f"{year}年是平年。")

# 7. 输出最终结果
print(f"结论:{date_str} 是{year}年的第 {total_days} 天。")
你输入的日期是: 2012-03-05 00:00:00
解析得到:2012年 3月 5日
计算基础天数(按平年算): 59(前几个月) + 5(当日) = 64天
2012年是闰年。
因为月份 > 2,总天数加1,变为: 65天
结论:2012/03/05 是2012年的第 65 天。

我们来验证一下:2012年是闰年,所以1月(31天)+2月(29天)=60天,再加上3月的5天,正好是65天。我们的“侦探”破案成功!

📝 动手练一练

  1. 修改测试:将上面程序中的 date_str 变量值改为你自己的生日(格式如1995/08/23),运行一下,看看你的生日是那年的第几天?
  2. 闰年挑战:分别测试2000/03/01和1900/03/01,观察程序输出的结果,理解“百年不闰”和“四百年再闰”的规则是如何生效的。
  3. 元组探索:如果我们想用列表 [31, 28, 31, 30, ...] 来代替程序中的元组,程序需要修改吗?哪些地方可以不改,哪些地方必须改?
👉 点击查看第3题思路提示

思路:元组和列表在访问元素和切片操作(如 [: month-1])上的用法是完全一样的。因此,如果只是简单地将定义元组的圆括号 () 换成定义列表的方括号 [],程序很可能不需要任何其他修改就能正常运行。

你可以尝试这样做:

  1. 找到代码中定义 days_in_month_tup 的那一行。
  2. 把 (31, 28, 31, ...) 外面的圆括号 () 改成方括号 []。
  3. 运行程序,看看是否还能得到正确结果。

这说明了列表和元组在很多基础操作上是相通的。它们最大的区别,我们之前已经演示过了,就在于能否修改。在这个程序里,月份天数数据不需要修改,所以两者都可以。在下一节2.0版本中,我们会专门探讨如果用列表,还能玩出什么新花样。

本章小结

恭喜你!你已经完成了“日期侦探”项目的1.0版本。你不仅学会了如何用程序判断闰年这个经典问题,还认识了一个新的数据结构——元组(tuple),并把它用在了存储固定数据的场景中。

📋 行动清单

学完立刻可以:

  • 运行你的“侦探程序”,算出今天是你今年生活中的第几天。
  • 向朋友炫耀一下,用程序快速判断1900年到底是不是闰年。
  • 思考一下:你的手机通讯录(姓名-电话)这种数据,适合用列表、元组还是我们以后会学的其他工具来存?

在下一节,我们将对这个侦探程序进行“升级”,看看如果用回我们熟悉的列表,代码会有什么不同,又会带来哪些新的可能性。

—— 小象教研组

配套资料 · 直接下载

课件、代码、数据集等配套资料全部免费,点击即可直接下载,无需分享或解锁。

  • 第6章代码包:判断第几天(含全部版本 4 个 .py)
    ZIP · 3KB
    下载
看图文没弄懂?展开看本节视频讲解(约 22 分钟)
📺 正在播放小象学院官方高清录播(支持倍速与清晰度调节)