整数的日期和月份

时间:2015-08-17 09:57:39

标签: python

有人可以告诉我如何从表示一年中某一天的整数中获取日期和月份吗?例如,32应该是2月1日,308应该是11月11日

我写了一个代码来返回值,但是很长,并且无法同时返回两个值,一个月和一天。

def normyear(fix):
    if fix > 31 :
        if fix > 59 :
            if fix > 90 :
                if fix > 120 :
                    if fix > 151 :
                        if fix > 181 :
                            if fix > 212 :
                                if fix > 243 :
                                    if fix > 273 :
                                        if fix > 304 :
                                            if fix > 334 :
                                                if fix > 365 :
                                                       print "Invalid id number                        please try again"
                                                else :
                                                    day = (fix - 334)
                                                    month = 12
                                            else :
                                                day = (fix - 304)
                                                month = 11
                                        else :
                                            day = (fix - 273)
                                            month = 10
                                    else :
                                        day = (fix - 243)
                                        month = 9
                                else :
                                    day = (fix - 212)
                                    month = 8
                            else :
                                day = (fix - 181)
                                month = 7
                        else :
                            day = (fix - 151)
                            month = 6
                    else :
                        day = (fix - 120)
                        month = 5
                else :
                    day = (fix - 90)
                    month = 4
            else :
                day = (fix - 59)
                month = 3
        else :
            day = (fix - 31)
            month = 2
    else :
        day = mid   
        month = 1
    return day
    return month

3 个答案:

答案 0 :(得分:4)

您可以使用datetime.strptime来解析此问题:

optional

请注意,您需要提供一年才能正确处理闰年。在这个例子中,我将当前的2015年硬编码到其中。

如果你想手动去那里,而不使用>>> from datetime import datetime >>> dayOfYear = 64 >>> d = datetime.strptime('{} 2015'.format(dayOfYear), '%j %Y') >>> d.day 5 >>> d.month 3 模块来处理这个问题,你也可以这样解决:

datetime

这与你的代码类似,只是逻辑更简单:只要剩下的天数比当前月份多,就会减去一个月的天数。这样做时,它会计算传递的月份(在此处使用>>> months = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] >>> dayOfYear = 64 >>> for month, monthDays in enumerate(months): if dayOfYear - monthDays > 0: dayOfYear -= monthDays else: print('Month:', month + 1) # +1 because it’s zero-indexed print('Day:', dayOfYear) break Month: 3 Day: 5 )。所以最后,剩余的日子是一个月的日子,过去的月数是月份。

答案 1 :(得分:3)

由于闰年,您将需要年份以及一年中的某一天。那说:

from datetime import datetime
from datetime import timedelta

def month_and_day_from_year_day(year, day):
    date = datetime(year, 1, 1) + timedelta(day - 1)
    return (date.month, date.day)

答案 2 :(得分:1)

下面的代码比较了各种日期和日期的速度。月算法。它还有一些用于测试这些算法的函数。和Poke& amp; Cyphase的算法我还包括使用奥术算法执行计算的算法。

我不会详细介绍,但算术算法的工作原理是将日历旋转到2月份的年末。旋转的日历比正常日历更加规则:它包含5个月的重复块。在每个区块中有153天,月长度从长到短交替。

#!/usr/bin/env python

''' daynum tests

Time various algorithms to compute the day & month
given the year and the day number

From http://stackoverflow.com/q/32047520/4014959

Typical timing results:

daynum_to_daymon0:  Poke 1
[3.0101921558380127, 3.058804988861084, 3.0825381278991699]
daynum_to_daymon1:  PM 2Ring 
[0.1977241039276123, 0.20353794097900391, 0.20514988899230957]
daynum_to_daymon2:  Cyphase 
[0.28950190544128418, 0.29159307479858398, 0.31502914428710938]
daynum_to_daymon3:  Poke 2 
[0.36095499992370605, 0.38256311416625977, 0.4053041934967041]

'''

from datetime import datetime, timedelta
from timeit import Timer

def is_leap(year):
    return (year % 4 == 0) and (year % 100 != 0) or (year % 400 == 0)

def daynum_to_daymon0(daynum, year):
    ''' Poke 1'''
    dy = '{0} {1}'.format(daynum, year)
    d = datetime.strptime(dy, '%j %Y')
    return d.day, d.month

def daynum_to_daymon1(daynum, year):
    ''' PM 2Ring '''
    isleap = is_leap(year)
    d = (daynum - 60 - isleap) % (365 + isleap)
    mon, day = divmod(d * 5 + 2, 153)
    return day // 5 + 1, (mon + 2) % 12 + 1

def daynum_to_daymon2(day, year):
    ''' Cyphase '''
    date = datetime(year, 1, 1) + timedelta(day - 1)
    return date.day, date.month

def daynum_to_daymon3(dayOfYear, year):
    ''' Poke 2 '''
    months = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
    months[1] += is_leap(year)
    for month, monthDays in enumerate(months):
        if dayOfYear - monthDays > 0:
            dayOfYear -= monthDays
        else:
            break
    return dayOfYear, month + 1

funcs = (
    daynum_to_daymon0,
    daynum_to_daymon1,
    daynum_to_daymon2,
    daynum_to_daymon3,
)

def dump_year(daynum_to_daymon, year):
    ''' Print a list of days for each month of the year '''
    isleap = is_leap(year)
    print daynum_to_daymon.func_name
    print year, ('!=', '==')[isleap], 'leap year'

    oldm = ''
    for daynum in range(1, 1 + 365 + isleap):
        d, m = daynum_to_daymon(daynum, year)
        if m != oldm:
            if oldm:
                print oldm, buff
            oldm = m
            buff = []
        buff.append(d)

    if buff:
        print oldm, buff

def compare(func0, func1, y0, y1):
    ''' Verify that 2 functions produce the same results 
        for years in the range(y0, y1) 
    '''
    print 'Comparing %s and %s' % (func0.func_name, func1.func_name)
    print 'Testing %d to %d (inclusive)' % (y0, y1)
    for year in range(y0, y1+1):
        isleap = is_leap(year)
        for daynum in range(1, 1 + 365 + isleap):
            t0 = func0(daynum, year)
            t1 = func1(daynum, year)
            assert t0 == t1, (t0, t1)
    print 'OK'

def test(daynum_to_daymon, y0, y1):
    ''' Compute day & month for all days in the given (inclusive) year range
        No output is generated because this function is used to perform 
        timeit tests
    '''
    for year in range(y0, y1+1):
        for daynum in range(1, 366 + is_leap(year)):
            t = daynum_to_daymon(daynum, year)

def time_test():
    reps, loops = 3, 60

    for func in funcs:
        fname = func.func_name
        print '%s: %s' % (fname, func.__doc__)

        setup = 'from __main__ import test, %s' % fname
        t = Timer('test(%s, 1995, 1996)' % fname, setup)
        r = t.repeat(reps, loops)
        r.sort()
        print r

if __name__ == "__main__":
    dump_year(daynum_to_daymon1, 2015)
    compare(daynum_to_daymon0, daynum_to_daymon1, 1995, 2015)
    time_test()

典型输出

daynum_to_daymon1
2015 != leap year
1 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31]
2 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28]
3 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31]
4 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30]
5 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31]
6 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30]
7 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31]
8 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31]
9 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30]
10 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31]
11 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30]
12 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31]
Comparing daynum_to_daymon0 and daynum_to_daymon1
Testing 1995 to 2015 (inclusive)
OK
daynum_to_daymon0:  Poke 1
[2.8590669631958008, 2.9910919666290283, 3.0923340320587158]
daynum_to_daymon1:  PM 2Ring 
[0.20377802848815918, 0.20526909828186035, 0.21576380729675293]
daynum_to_daymon2:  Cyphase 
[0.29232597351074219, 0.29248213768005371, 0.2969820499420166]
daynum_to_daymon3:  Poke 2 
[0.34156394004821777, 0.34333705902099609, 0.34701800346374512]

虽然算术算法速度最快,但我建议使用Cyphase算法,除非你真的需要速度(在这种情况下,你用Python做什么?)。 Cyphase的算法更易于阅读和阅读。了解;算术算法确实需要大量记录,以解释如何&它为何有效。使用"聪明"像这样的算法违反了Kernighan's Maxim

  

每个人都知道调试的难度是编写程序的两倍   第一名。所以,如果你在写作时能够像你一样聪明   它,你将如何调试它?