当前位置: 首页> 财经> 股票 > 编程珠玑之第三章习题3-4

编程珠玑之第三章习题3-4

时间:2025/7/12 14:22:29来源:https://blog.csdn.net/qq_62835094/article/details/142064958 浏览次数:0次

问题

4.编写处理如下日期的函数:给定两个日期,计算两者之间的天数;给定一个日期,返回值为周几;给定月和年,使用字符数组生成该月的日历。

思路

分为三个小问
第一问
计算日期差,我们用图来解释具体计算逻辑

在这里插入图片描述

如图所示,d1, d2之差为绿色画线部分。我们从年份的角度入手,上图可以划分为三块:d1所在年份,中间年份,d2所在年份

具体计算逻辑如下
d1年剩下天数 + 中间年份包含天数 + d2所在年份经历的天数

计算天数的时候,需要将闰年因素考虑进去,也就是对最终计算结果增加修正逻辑

第二问
返回周几?
这一问就简单很多了,我们只需要计算当前日期经历的天数,然后对7整除,即可得到本周是周几

第三问
返回数组,生成日历
生成日历的关键点,就是弄清楚本月第一天是周几。弄清楚这一点后,创建数组时,添加额外的元素,直到月初第一天排序到正确的下标,表示正确的星期几即可

代码

简单说一下代码思路,为了更方便编写,做了一些抽象

Timer
month_day: int
is_leap_year(year) : Boolean
Date
year: int
month: int
day: int
day_convert() : int
year_diff() : int
get_week_day() : int
get_day_count_of_month() : int
Calendar
day_bigger(Date, Date) : Boolean
day_diff(Date, Date) : int
get_week(Date) : int
print_month(year, month) : int

Timer抽象出Calendar,Date共有的一些方法和变量

Date用于表示日期,其中包含一些处理日期的方法

Calendar用于处理日期与日期之间关系,并对日期做出更为复杂的处理。Calendar包含的三个方法,直接对应题目要求的三个问题

'''
时间基类
'''class Timer:month_day = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]def __init__(self):pass@staticmethoddef is_leap_year(year):if (year % 4 == 0 and year % 100 != 0) or (year % 400 == 0):return Trueelse:return False'''
日期类, 继承时间类
'''class Date(Timer):def __init__(self, year: int, month: int, day: int):super().__init__()  # 调用父类的构造函数self.year = yearself.month = monthself.day = day'''转化为天数'''def day_convert(self) -> int:if self.month == 1:return self.dayif self.month == 2:return 31 + self.dayday = sum(Timer.month_day[0:self.month - 1]) + self.day# 如果是闰年, + 1return day + (1 if Timer.is_leap_year(self.year) else 0)'''年做差'''def year_diff(self, d2: 'Date') -> int:return self.year - d2.year'''获取当前日期所在week的day'''def get_week_day(self) -> int:days = self.day_convert()week_day = days % 7return 7 if week_day == 0 else week_day'''获取当前月份的天数 '''def get_day_count_of_month(self) -> int:day_count = Timer.month_day[self.month - 1]return day_count + (1 if Timer.is_leap_year(self.month) else 0)'''
日历类, 继承时间类
'''class Calendar(Timer):def __init__(self):super().__init__()  # 调用父类的构造函数@staticmethoddef day_bigger(d1: Date, d2: Date) -> int:day1, day2 = d1.day_convert() + d1.year * 365, d2.day_convert() + d2.year * 365if day1 > day2:return 1elif day1 < day2:return -1else:return 0'''获取日期之差'''def day_diff(self, date1: Date, date2: Date) -> int:# 日月转换_d1, _d2 = date1, date2bigger_flag = Calendar.day_bigger(_d1, _d2)if bigger_flag == -1:_d1, _d2 = _d2, _d1day1, day2 = _d1.day_convert(), _d2.day_convert()# 年做差year_diff = _d1.year_diff(_d2)days = 0if _d1.year == _d2.year:days = day1 - day2else:# 计算核心逻辑: _d1年剩下天数 + 中间年份包含天数 + _d2所在年份经历的天数days = (Date(_d2.year, 12, 31).day_convert() - day2) + (year_diff - 1) * 365 + day1# 修正for year in range(_d1.year + 1, _d2.year):if self.is_leap_year(year):days += 1return -days if bigger_flag == -1 else days'''获取当前日期所在week '''@staticmethoddef get_week(d: Date) -> int:days = d.day_convert()return days // 7 + (0 if days % 7 == 0 else 1)@staticmethoddef print_month(year, month):d = Date(year, month, 1)week_day = d.get_week_day()week_list = ['' for _ in range(week_day - 1)]for day in range(1, d.get_day_count_of_month() + 1):week_list.append(day)# 处理成二维数组row_count = len(week_list)//7 + (1 if len(week_list) % 7 != 0 else 0)res = [week_list[i * 7:(i * 7) + 7] for i in range(row_count)]for row in res:print(row)

测试

测试代码使用python自带的时间模块检验编写代码的正确性。如果使用我编写的时间模块计算得到的答案和python自带的时间模块得到的答案相同,那么说明我编写的代码没有问题

def test_day_diff():from datetime import datetime# 定义两个日期字符串date_str1 = "2020-02-10"date_str2 = "2024-01-30"# 将字符串转换为datetime对象date_format = "%Y-%m-%d"date1 = datetime.strptime(date_str1, date_format)date2 = datetime.strptime(date_str2, date_format)# 计算两个日期之间的差值delta = date1 - date2# 输出日期差值print("两个日期相差:", delta.days, "天")d1 = Date(2020, 2, 10)d2 = Date(2024, 1, 30)c = Calendar()print(c.day_diff(d1, d2))def test_get_week():from datetime import datetime# 定义日期字符串date_str = "2024-09-09"# 设置日期格式date_format = "%Y-%m-%d"# 将字符串转换为datetime对象date_obj = datetime.strptime(date_str, date_format)# 使用isocalendar()方法获取ISO周数year, week_num, _ = date_obj.isocalendar()# 输出结果print(f"{date_str}{year} 年的第 {week_num} 周。")d1 = Date(2024, 9, 9)c = Calendar()print(c.get_week(d1))def test_print_month():Calendar.print_month(2024, 9)test_day_diff()
test_get_week()
test_print_month()

在这里插入图片描述
正确!

关键字:编程珠玑之第三章习题3-4

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: