月份的第一天很容易構建,因爲是第一次下個月的一天。一旦你有這些,其餘的更容易。正如OP所指出的那樣,calendar.monthrange
function爲我們提供了最可讀的方法來獲取一個月的最後一天。
>>> from datetime import date, year
>>> import calendar
>>> def first_day(dt):
... # Simply copy year and month into new date instance
... return date(dt.year, dt.month, 1)
...
>>> def last_day(dt):
... days_in_month = calendar.monthrange(dt.year, dt.month)[1]
... return date(dt.year, dt.month, days_in_month)
...
>>> nth_day = 32
>>> day_of_year = date(2012, 1, 1) + timedelta(days=nth_day - 1)
>>> day_of_year
datetime.date(2012, 2, 1)
>>> first_day(day_of_year), last_day(day_of_year)
(datetime.date(2012, 2, 1), datetime.date(2012, 2, 29))
>>> day_of_year - first_day(day_of_year), last_day(day_of_year) - day_of_year
(datetime.timedelta(0), datetime.timedelta(28))
將這些技術結合成一個功能:
def delta_to_start_and_end(year, day_of_year):
dt = date(year, 1, 1) + timedelta(days=(day_of_year - 1))
def first_day(dt):
return date(dt.year, dt.month, 1)
def last_day(dt):
days_in_month = calendar.monthrange(dt.year, dt.month)[1]
return date(dt.year, dt.month, days_in_month)
return (dt - first_day(dt)).days, (last_day(dt) - dt).days
輸出:
>>> delta_to_start_and_end(2012, 32)
(0, 28)
>>> delta_to_start_and_end(2011, 32)
(0, 27)
>>> delta_to_start_and_end(2012, 34)
(2, 26)
>>> delta_to_start_and_end(2012, 364)
(28, 2)
我不知道,如果你想添加1
每兩個值;目前這個月的第一天(第一個例子)給出0
作爲第一個值和(第二個月的天數-1)作爲第二個值,因爲這是與這些點的天數之差。如果您需要這些,在delta_to_start_and_end
函數的最後一行添加+ 1
兩次是微不足道的。
作爲一個歷史悠久的音符,這個答案的先前版本使用不同的方法來計算一個月的最後一天沒有日曆模塊:
def last_day(dt):
rest, month = divmod(dt.month, 12)
return date(dt.year + rest, month + 1, 1) - timedelta(days=1)
此功能使用divmod
builtin function處理「當月是十二月份的邊緣案例;在這種情況下,下個月不是13
,而是1
,我們還需要增加一年。將數字回滾到「開始」是數字的模數,但divmod
函數也給出了除數,如果當前月份爲12
,恰好爲1
。這給了我們一個方便的指標,何時增加一年。
你能否澄清你的例子。它很難遵循。你試過了什麼?你想要什麼作爲你的輸出? –
一年中的第32天是2月1日;一月有31天。 –
您需要將年份轉換爲您的功能,因爲有些年份的日期不同 – GP89