目的:
給定一個年月區間,比如:2019.01 至 2019.05,要求返回一個包含期間所有的月份的列表,比如:['2019.01', '2019.02', '2019.03', '2019.04', '2019.05']
參考博客:https://blog.csdn.net/qq_32502511/article/details/84400638
Note:參考的博客代碼邏輯存在問題,若時間年份之差超過兩年,比如 2014 至 2016,計算結果就不對了,我在分析了其計算邏輯后,根據自身的功能需求,對函數功能進行了改進。
思路:
這里要求得到給定區間的所有月份,那么我們先可以計算給定區間的時間差,即兩者之間總共包含多少個月;之后由第一個月(起始時間)逐步累加,最終得到給定時間區間的所有月份的列表。
1.時間差計算:我們可以使用第三方庫 dateutil 中的 rrule.count 函數來實現。
首先看下以下代碼:
import datetime from dateutil import rrule start=datetime.datetime.strptime('2019.01','%Y.%m') end=datetime.datetime.strptime('2019.05','%Y.%m') print(start.month) rrule.rrule(rrule.MONTHLY,dtstart=start,until=end).count()
輸出結果如下:
在上面的代碼中,我們使用了 rrule.count 函數 以月份為尺度,計算量兩個時間段之間的差,得到了 2019.01 至 2019.05 這段時間里,總共有5個月。
2.累加計算每個月:在這里我們可以利用 for 循環以及 range() 函數,根據總月份數量,逐步累加,比如:2019.01 - 2019.05 共5個月,從0到4進行迭代,由 1+0=1 到 1+4=5,即可得到所有月份;另外,當月份迭代累加結果超過12時,對累加結果除以12取余,並對年份進行加1,即可得到正確的年月時間。
解析:
Python 第三方庫 dateutil 提供了 rrule.count() 方法,方便我們計算時間差,它有以下特點:
① rrule 方法允許用戶根據日期(DAILY),星期(WEEKLY),月(MONTHLY),年(YEARLY)來設置時間差計算的尺度。
② count()返回的結果是一個整數。
代碼實現:
根據上面的思路,定義以下函數:
import datetime
from dateutil import rrule def get_each_month(start_month, end_month): if str(start_month).count('.') != 1 or str(end_month).count('.') != 1: print("Parameter Error: Pls input a string such as '2019.01'") return[] if int(str(start_month).split('.')[1]) > 12 or int(str(end_month).split('.')[1]) > 12: print('Parameter Error: Pls input correct month range such as between 1 to 12') return[] if int(str(start_month).split('.')[1]) == 0 or int(str(end_month).split('.')[1]) == 12: print('Parameter Error: Pls input correct month range such as between 1 to 12') return[] start = datetime.datetime.strptime(start_month, "%Y.%m") end = datetime.datetime.strptime(end_month, "%Y.%m") month_count = rrule.rrule(rrule.MONTHLY,dtstart=start,until=end).count() #計算總月份數 if end < start: print("Parameter Error: Pls input right date range,start_month can't latter than end_month") return [] else: list_month = [] year = int(str(start)[:7].split('-')[0]) #截取起始年份 for m in range(month_count): #利用range函數填充結果列表 month = int(str(start)[:7].split('-')[1]) #截取起始月份,寫在for循環里,作為每次迭代的累加基數 month = month + m if month > 12: if month%12 > 0: month = month%12 #計算結果大於12,取余數 if month==1: year += 1 #只需在1月份的時候對年份加1,注意year的初始化在for循環外 else: month = 12 if len(str(month))==1: list_month.append(str(year) + '.0' + str(month)) else: list_month.append(str(year) + '.' + str(month)) return list_month
調用結果如下: