1 #!/usr/bin/env python
2 #-*- coding:utf-8 -*-
3
4
5 """
6 ADT Date: #定义日期对象的抽象数据类型7 Date(self, int year, int month, int day) #构造表示year/month/day的对象8 difference(self, Date d2) #求出self和d2的日期差9 plus(self, int n) #计算出日期第self之后n天的日期10 num_date(self, int year, int n) #计算year年第n天的日期11 adjust(self, int n) #将日期d调整n天(n为带符号整数)12 year(self) #返回日期的年13 month(self) #返回日期的月14 day(self) #返回日期的天15 """
16
17 classDate(object):18 __slots__ = ('_year', '_month', '_day')19
20 def __init__(self, year, month, day):21 if not isinstance(year, int) or not isinstance(month, int) or notisinstance(day, int):22 raiseTypeError23
24 if 1800<=year
56 defdifference(self, other):57 #日期差
58 DateDiff =059 if self._year >other._year:60 #换个位置,方便计算
61 tmp =(self._year,self._month,self._day)62 (self._year,self._month,self._day) =(other._year,other._month,other._day)63 (other._year, other._month, other._day) =tmp64
65 #两个年之间的年直接加它一年的天数,分闰年和非闰年区别366和365
66 for i in range(self._year+1,other._year):67 ifDate.leap_year(i):68 DateDiff += 366
69 else:70 DateDiff += 365
71 #比较小的年,用后面的月份的天数相加在加上该月剩余的天数
72 for i in range(self._month+1, 13):73 DateDiff +=Date.month_day(self._year,i)74 DateDiff += Date.month_day(self._year,self._month) -self._day75
76 #比较大的年,加前面月份的天数加上本月的天数
77 for i in range(1,other._month):78 DateDiff +=Date.month_day(other._year,i)79 DateDiff +=other._day80 returnDateDiff81
82 defplus(self,n):83 if notisinstance(n,int):84 raiseTypeError85 if n<0:86 raise ValueError("%d is not valid,must >= 0" %n)87 self._day +=n88 while self._day >Date.month_day(self._year,self._month):89 self._day -=Date.month_day(self._year,self._month)90 self._month += 1
91 if self._month == 13:92 self._month = 1
93 self._year += 1
94 returnDate(self._year, self._month, self._day)95
96 defnum_date(self, year, n):97 if not isinstance(year, int) or notisinstance(n, int):98 raiseTypeError99 ifDate.leap_year(year):100 if n>366 and n<1:101 raiseValueError102 else:103 if n>365 and n<1:104 raiseValueError105 self._year =year106 #判该n对应的月份和天数
107 for i in range(1,13):108 d =n109 n -=Date.month_day(year,i)110 if n<=0:111 self._month =i112 self._day =d113 break
114 returnDate(self._year, self._month, self._day)115
116 defadjust(self,n):117 if notisinstance(n,int):118 raiseTypeError119 #n为正的情况
120 if n>=0:121 self.plus(n)122 #n为负的情况
123 else:124 self._day +=n125 while self._day <0:126 if self._month -1 ==0:127 self._month = 13
128 self._year -= 1
129 self._day += Date.month_day(self._year, self._month-1)130 self._month -= 1
131 returnDate(self._year, self._month, self._day)132
133 def __str__(self):134 return str(self._year) + "-" + str(self._month) + "-" +str(self._day)135
136
137 defyear(self):138 returnself._year139
140 defmonth(self):141 returnself._month142
143 defday(self):144 returnself._day145
146 @staticmethod147 defleap_year(year):148 if (year % 4 == 0 and year % 100 != 0) or year % 400 ==0:149 returnTrue150 else:151 returnFalse152
153 #每月的天数,字典实现
154 @staticmethod155 defmonth_day(year,month):156 d ={}157 bigmonth = (1,3,5,7,8,10,12)158 smallmonth = (4,6,9,11)159 for i in range(1,13):160 if i inbigmonth:161 d[i] = 31
162 elif i insmallmonth:163 d[i] = 30
164 elif i == 2:165 ifDate.leap_year(year):166 d[i] = 29
167 else:168 d[i] = 28
169 returnd[month]170
171
172 if __name__=='__main__':173 d = Date(2003,12,10)174 d1 = Date(2005,2,28)175 print(d)176 print("===")177 print(d.difference(d1))178 d.plus(30)179 print("===")180 print(d)181 print("===")182 d3 = Date(2006,12,13)183 d3.num_date(2016,10)184 print(d3)185 d3.adjust(-20)186 print("===")187 print(d3)