關於實現今天到一年中任意一天兩者之間的天數差的計算
昨天的某時某刻突發奇想,想用自己現階段所學的python知識來製作一個小程式。大致功能為:開機時像某安全軟體一樣,彈出視窗,視窗上能提示你,“距xxxx年xx月xx日還有多少天”。
在開始前,因為涉及到日期的計算(如標題所說),首先我想到了標準庫中的datetime模組,該模組有個today()函式能返回今天的日期(格式:xxxx-xx-xx),將函式返回的日期轉換成字串後,日期就成了一個長度為10的字串,對字串進行切片後分別轉換為整型數,就可得到year,month,day引數,具體程式碼如下
1 from datetime import date 2 3 4 def get_date(): 5today_date = date.today() 6str_t_d = str(today_date) 7year = int(str_t_d[:4]) 8month = int(str_t_d[5:7]) 9day = int(str_t_d[-2:]) 10return year, month, day
呼叫get_date()後會返回元組(year, month, day)
下一步開始計算天數差了,因為考慮到對於每一年來說,每個月份天數除了2月以外都是固定的,2月天數的變化關係受到年份影響,因此需要判斷閏年或平年,程式碼如下
1 def is29days(year=get_date()[0]): 2months = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] 3if year % 100 == 0: 4if year % 400 == 0: 5months[1] = 29 6return months 7else: 8return months 9elif year % 4 == 0: 10months[1] = 29 11return months 12else: 13return months
在上述程式碼中,將一年的十二個月對應天數按順序放在列表months中,這個列表中二月對應的天數為28天,即預設為平年,用 if-elif-else語句判斷是否為閏年,是就改變months[1]的值為29,返回新的months列表,否返回預設列表,在呼叫is29days()時將返回月份列表
有了月份列表,就可也計算了,假定,給定一個日期:3月6日,今天的日期:get_date()[1] 月get_date()[2](今天日期為2月12日,沒錯我是今天寫的)日,利用兩個日期的月份對months列表切片,結合列表索引值將其與月份對應,如果當月為2月,則對應的months列表索引值為2-1=1!!!,切片為:months[2-1 : 3],這樣列表中就包含了2月,3月兩個月,用sum計算切片後的列表元素和後,減去兩頭的天數後就可以得到3月6日與2月12日之間相差的天數了,程式碼如下
1 def count_days(num_month=3, d_day=6): 2if num_month < get_date()[1] and d_day < get_date()[2]: 3'''在上一月的情況''' 4msg = 'error' 5month = 'error' 6year = 'error' 7x_day = 'error' 8return msg, month, year, x_day 9elif num_month == get_date()[1] and d_day < get_date()[2]: 10'''在當月前些天的情況''' 11msg = 'error' 12month = 'error' 13year = 'error' 14x_day = 'error' 15return msg, month, year, x_day 16else: 17months = is29days()[get_date()[1]-1:num_month] 18x_day = d_day 19year = get_date()[0] 20month = num_month 21days = sum(months) - get_date()[2] - months[-1] + x_day 22msg = '%3s天' % days 23return msg, month, year, x_day
考慮到會有選擇的日期在當日日期之前的情況,加入判斷語句,呼叫count_days()後返回元組(msg, month, year, x_day),(若不傳遞實參 ,則預設實參為num_month=3, d_day=6)
現在就完成了天數差的計算,但開頭所講我們還需一個能彈出視窗(GUI介面),鑑於我僅僅接觸過 tkinter 所以我使用了它,程式碼如下
1 deadline = Tk() 2 deadline.title('DeadLine') 4 deadline.geometry('220x300+1678+732') 6 label = Label(deadline, text='距%4s年%2s月%2s日還有' % (count_days()[2], count_days()[1], count_days()[3]) 7 label.grid(row=0, columnspan=2) 8 label_1 = Label(deadline, justify='left', text=""" 9 Don`t waste time any more ! 10 11 " So do you want to take a 12 leap of faith,or become an 13 old man,filled with regret 14 waiting to die alone? " 15 """) 16 label_1.grid(row=2, columnspan=2) 17 display = Listbox(deadline, font=100, width=5, height=1) 18 display.insert(END, count_days()[0]) 19 display.grid(row=1, columnspan=2) 22 button_2 = Button(deadline, text='Exit', command=deadline.destroy) 23 button_2.grid(columnspan=2) 24 deadline.mainloop()
效果如下
好像差不多了啊
然後開始將其封裝成一個.exe的檔案,在這裡使用第三方庫PyInstaller,因為不是python自帶的需要自己安裝,安裝完成後,在控制檯輸入命令pyinstaller -F -w filename.py,這裡需要注意如果不是在filename.py檔案所在的目錄下開啟的控制檯,是需要給定路徑的,同時F 大寫,w小寫,如果不加上-w選項,在執行程式時會彈出控制器介面,同時py檔名不能用漢字,否則會報錯,完成後在當前目錄下,會有一個dist檔案件,開啟會發現一個filename.exe檔案,大功告成!!
還沒完,我想每天開啟電腦都能看到上圖的GUI介面,就像某安全軟體在螢幕右下角彈出介面一樣(好像安全軟體都彈),上網查了一下,找到一個方法,如下
https://jingyan.baidu.com/article/54b6b9c0d103662d593b474e.html
完整的程式碼如下:
1 #!/usr/bin/env python3 2 # coding=utf-8 3 # Date: 2019/2/12 4 5 from tkinter import * 6 from datetime import date 7 8 9 def get_date(): 10today_date = date.today() 11str_t_d = str(today_date) 12year = int(str_t_d[:4]) 13month = int(str_t_d[5:7]) 14day = int(str_t_d[-2:]) 15return year, month, day 16 17 18 def is29days(year=get_date()[0]): 19months = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] 20if year % 100 == 0: 21if year % 400 == 0: 22months[1] = 29 23return months 24else: 25return months 26elif year % 4 == 0: 27months[1] = 29 28return months 29else: 30return months 31 32 33 def count_days(num_month=3, d_day=6): 34if num_month < get_date()[1] and d_day < get_date()[2]: 35'''在上一月的情況''' 36msg = 'error' 37month = 'error' 38year = 'error' 39x_day = 'error' 40return msg, month, year, x_day 41elif num_month == get_date()[1] and d_day < get_date()[2]: 42'''在當月前些天的情況''' 43msg = 'error' 44month = 'error' 45year = 'error' 46x_day = 'error' 47return msg, month, year, x_day 48else: 49months = is29days()[get_date()[1]-1:num_month] 50x_day = d_day 51year = get_date()[0] 52month = num_month 53days = sum(months) - get_date()[2] - months[-1] + x_day 54msg = '%3s天' % days 55return msg, month, year, x_day 56 57 58 deadline = Tk() 59 deadline.title('DeadLine') 60 deadline.geometry('220x300+1678+732') 61 label = Label(deadline, text= 62 '距%4s年%2s月%2s日還有' % (count_days()[2], count_days()[1], count_days()[3])) 63 label.grid(row=0, columnspan=2) 64 label_1 = Label(deadline, justify='left', text=""" 65 Don`t waste time any more ! 66 67 " So do you want to take a 68 leap of faith,or become an 69 old man,filled with regret 70 waiting to die alone? " 71 """) 72 label_1.grid(row=2, columnspan=2) 73 display = Listbox(deadline, font=100, width=5, height=1) 74 display.insert(END, count_days()[0]) 75 display.grid(row=1, columnspan=2) 76 button_2 = Button(deadline, text='Exit', command=deadline.destroy) 77 button_2.grid(columnspan=2) 78 deadline.mainloop()
寫在最後:
上述程式碼只是實現了最簡單的情況,我想以此為基礎製作一個能計算任意兩個日期天數差的程式,一步一步來,day day up,Come on ,code newbie!