【Time系列四】查询各月份的日历

荒废了两个星期没学java了,今天一心想突破"日历查询"这个小程序。先用比较简单的python实现下。

无奈天资愚钝,想了一个上午。最后卡在了日期排列的问题上,只好去参考下别人的代码。

 参考CSDN大牛: http://blog.csdn.net/jlshix/article/details/46970563

 

从简单的开始,想想既然是查询日历。打开下手机,大体是这种模样。那么我们就按照这种格式,来

设计程序吧。

首先,之前讲到的,用(%)求余符号求星期的。今天是10月30号—周日,那么如何求出若干天后是星

期几呢? 思路就是,我们把周日定为0,一天后的周一自然就是1,依此类推,周六就是六啦。那么13

天后,就是(0+13) % 7 = 5, 周五哦......

 1 # coding: utf-8
 2 
 3 print u"今天是周日!"
 4 query = raw_input(">>> ")
 5 
 6 weeks = {
 7     0: u"周日",
 8     1: u"周一",
 9     2: u"周二",
10     3: u"周三",
11     4: u"周四",
12     5: u"周五",
13     6: u"周六",
14 }
15 
16 print query + u"天后是" + weeks[(int(query) + 0) % 7] 

------------------------------------------------------------------------------------------------------------------------------------------------------------

现在就利用之前做过的自动关机脚本的原理,以1970年1月1日午夜零点,也就是周四为基点。来算出从它

到现在总共过了多少秒,然后再转化为总共多少天,再算出若干天之后是星期几。

【注: 2016年10月31号是周一】

 1 # coding: utf-8
 2 
 3 import time
 4 import datetime
 5 #--------------------------------------------#
 6 # 把当前的时间转化为指定格式 "年/月/日 时:分:秒"   #
 7 # 把当前时间转化为datetime.datetime的类型       #
 8 # 得出从1970年元旦0点至今的总秒数                #
 9 # 再将总秒数转化为总天数                        #
10 #---------------------------------------------#
11 currTime = time.strftime("%Y/%m/%d %H:%M:%S")
12 dt = datetime.datetime.strptime(currTime, "%Y/%m/%d %H:%M:%S")
13 currSeconds = time.mktime(dt.timetuple())
14 currDays = currSeconds / (3600 * 24)
15 
16 weeks = {
17     0: u"周日",
18     1: u"周一",
19     2: u"周二",
20     3: u"周三",
21     4: u"周四",
22     5: u"周五",
23     6: u"周六"
24 }
25 
26 print weeks[int((currDays + 4) % 7)]

 

 

 --------------------------------------------------------------------------------------------------------------------------------------------------------------

其实嘛,这个小程序的难点就在于日历日期的排版上。大家可以看出来,除了第一行和最后一行,每一行都是有七个数。

所以重点就在于找出第一个数字也就是每个月的1号到底是周几。然后根据0对应周日,1对应周一等等按空格排列。从第

一个数字的空格情况上可以推断。周六的话,距离行开头有5 * 6个空格,加上开头的三个空格。(一二三这些中文分别占

两个空格,字与字之间隔三个空格。)对于1之后的其它数字,都是"4d"占有四个空格(包括其自身)的位置。所以这个开头

的三个空格是不能省略的。

 1 # coding: utf-8
 2 
 3 import time
 4 import datetime
 5 
 6 # 格式化日期: %Y表示年, %m表示月, %d表示日
 7 # 注意将字符串型(string)转换成整数型(int)
 8 year = int(time.strftime("%Y"))
 9 month = int(time.strftime("%m"))
10 day = int(time.strftime("%d"))
11 
12 #--------------------------------------------#
13 # 当前时间                                   #
14 # 把当前时间转化为datetime.datetime对象      #
15 # 自1970年1月1日以来到今天总共过了多少秒     #
16 # 直至今天总共过了多少天                     #
17 # 直至当月的1号总共过了多少天                #
18 #--------------------------------------------#
19 currTime = time.strftime("%Y/%m/%d %H:%M:%S")
20 dt = datetime.datetime.strptime(currTime, "%Y/%m/%d %H:%M:%S")
21 totalSeconds = time.mktime(dt.timetuple())
22 totalDays = totalSeconds / (3600 * 24)
23 start_day = int(totalDays -int(day) + 1)
24 
25 index = (4 + start_day) % 7
26 
27 def is_leap_year(year):
28     if year % 4 == 0 and year % 100 != 0 or year % 400 == 0:
29         return True
30     else:
31         return False
32 
33 def get_num_of_days_in_month(year, month):
34     if month in (1, 3, 5, 7, 8, 10, 12):
35         return 31
36     elif month in (4, 6, 9, 11):
37         return 30
38     elif is_leap_year(year):
39         return 29
40     else:
41         return 28
42 
43 def print_calender(year, month):
44     # 打印日历正文
45     # print + 逗号会多一个空格
46     print u"   < %s年%s月" % (year, month)
47     print "-----------------------------------"
48     print u"   日   一   二   三   四   五   六"
49 
50     for i in range(1, get_num_of_days_in_month(year, month) + 1):
51         if i == 1:
52             print "  ",                        # 打印行首的三个空格
53             print " " * 5 * index + "%d" % 1,  # 从星期几开始则空几个空格  
54         else:
55             print "%4d" % i,                   # 宽度控制, 4 + 1
56         if (4 + start_day + i - 1) % 7 == 6:
57             print                              # 当日期转到周六时换行
58 
59 print_calender(year, month)
查询当月日历

 上面这种是用到time 和 datetime 模块的,日期要转换为时间戳,稍显麻烦。所以下面我们用另一种直接计算天数的,

并且定义了多个函数,相信模块化的形式会更加便于理解。

 1 # coding: utf-8
 2 
 3 import time
 4 
 5 # 将日期格式化成字符串(string), 注意转换成整数型(int)
 6 year = int(time.strftime("%Y"))
 7 month = int(time.strftime("%m"))
 8 
 9 def is_leap_year(year):
10     # 判断是否闰年
11     if year % 4 == 0 and year % 100 != 0 or year % 400 == 0:
12         return True
13     else:
14         return False
15 
16 def get_num_of_days_in_month(year, month):
17     # 每个月有多少天, 闰年和平年的2月(平月)分别是29和28天
18     if month in (1, 3, 5, 7, 8, 10, 12):
19         return 31
20     elif month in (4, 6, 9, 11):
21         return 30
22     elif is_leap_year(year):
23         return 29
24     else:
25         return 28
26 
27 def get_total_days(year, month):
28     # 自从1970年1月1日以来过了多少天
29     days = 0
30     
31     for y in range(1970, year):
32         if is_leap_year(y):
33             days += 366
34         else:
35             days += 365
36     for m in range(1, month):
37         days += get_num_of_days_in_month(year, m)
38 
39     return days 
40 
41 def get_start_day(year, month):
42     # 返回每个月的1号是星期几
43     return (4 + get_total_days(year, month)) % 7
44 
45 def print_calender(year, month):
46     # 打印日历正文
47     print u"   < %s年%s月" % (year, month)
48     print "-----------------------------------"
49     print u"   日   一   二   三   四   五   六"
50     for i in range(1, get_num_of_days_in_month(year, month) + 1):
51         if i == 1:
52             print "   " + " " * 5 * get_start_day(year, month) + "%d" % 1, 
53         else:
54             print "%4d" % i,
55         if (get_start_day(year, month) + i - 1) % 7 == 6:
56             print 
57 
58 print_calender(year, month)
改进版

-------------------------------------------------------------------------------------------------------------------------------------

接下来是终极版的日历,只能查询当月的日历,实用性大打折扣。所以我们要能查到所有年份所有月份的日历,这才好玩!

 

 1 # coding: utf-8
 2 
 3 import re  # 导入正则表达式re: (regex)
 4 import time
 5 
 6 # 输入日期, 2016/11或2016-11或2016 11的格式均可
 7 # 用re.findall匹配所有数字, 并以列表的形式保存
 8 date = raw_input(u"请输入您想要查询的日期: ".encode("gbk"))
 9 date_list = re.findall("\d+", date)
10 year = int(date_list[0])
11 month = int(date_list[1])
12 
13 def is_leap_year(year):
14     # 判断是否闰年
15     if year % 4 == 0 and year % 100 != 0 or year % 400 == 0:
16         return True
17     else:
18         return False
19 
20 def get_num_of_days_in_month(year, month):
21     # 返回各个月的天数
22     # 注意: 闰年和平年的2月(平月)分别是29和28天
23     if month in (1, 3, 5, 7, 8, 10, 12):
24         return 31
25     elif month in (4, 6, 9, 11):
26         return 30
27     elif is_leap_year(year):
28         return 29
29     else:
30         return 28
31 
32 def get_total_days(year, month):
33     # 得出自1970年1月1日到指定日期的天数
34     total_days = 0
35     for y in range(1970, year):
36         if is_leap_year(y): 
37             total_days += 366
38         else:
39             total_days += 365
40     for m in range(1, month):
41         total_days += get_num_of_days_in_month(year, m)
42     return total_days
43 
44 def get_start_day(year, month):
45     # 得出每个月的1号是星期几
46     return (4 + get_total_days(year, month)) % 7
47     
48 def print_calender(year, month):
49     # 打印日历正文
50     # print + 逗号会多出一个空格
51     print u"   < %s年%s月" % (year, month)
52     print "------------------------------------"
53     print u"   日   一   二   三   四   五   六"
54      # 索引上限记得加1
55     for day in range(1, get_num_of_days_in_month(year, month) + 1):
56         if day == 1:
57             print "   " + " " * 5 * get_start_day(year, month) + "%d" % 1,
58         else:
59             print "%4d" % day,
60         if (get_start_day(year, month) - 1 + day) % 7 == 6:
61             print
62 
63 print_calender(year, month)
查询任意月份的日历

11月

 

10月

 

 2月

 

                                                                                                                                                       --------------- 11.2号早

posted @ 2016-10-31 19:23  坏小孩D_R  阅读(583)  评论(0编辑  收藏  举报