2012-06-22 35 views
0

與Python我想計算day_of_a_year一天三角洲天,其對應的月份,以及三角洲天爲一個月+ 1的Python:日期操作代碼

*對不起,我忘了提,今年是已知變量 例如。

def a(day_of_year): 
    <...> 
    return [(days_from_start_of_month),(days_untill_end_of_month)] 

所以 如果

day_of_year = 32 
a(32) = (2,28) #assuming the month which the day_of_year corresponds to starts from day 30 and ends to day 60. 

到目前爲止IM學習的日期時間,timeutils和日曆模塊,我真的想不出邏輯的代碼!我希望我有一些可以展示的東西,但是我會在timedelta函數的某個地方迷路。

+3

你能否澄清你的例子。它很難遵循。你試過了什麼?你想要什麼作爲你的輸出? –

+1

一年中的第32天是2月1日;一月有31天。 –

+0

您需要將年份轉換爲您的功能,因爲有些年份的日期不同 – GP89

回答

2

月份的第一天很容易構建,因爲是第一次下個月的一天。一旦你有這些,其餘的更容易。正如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。這給了我們一個方便的指標,何時增加一年。

+0

啊你注意到了天數= 31的問題,我只是想指出:P – GP89

+0

@ GP89:路在你前面! :-P –

+0

一個月的最後一天也可以用calendar.monthrange(year,month) - >(0〜6(0 = mon,6 = Sun),days_of_month) calendar.monthrange(2000,30) - >(3,31) – user528025

0

我不認爲有一個現有的庫適用於此。你必須讓自己的東西,這樣的:

monthdays = (31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31) 

day = 32 

total = 0 
for i in monthdays: 
    if day - total - i < 0: 
     before = day - total 
     after = total + i - day 
     break 
    total += i 

print before, after 

(只是一個快速啓動,有可能是一個更優雅的方式)

+1

這將在閏年中打破,如2012年。 –

+0

這就是爲什麼我說'只是一個快速入門':D – BrtH

+0

我想過這個,但不幸的是我不得不考慮閏年 – user528025