2015-03-24 3 views
2

Дано:строку на сегодняшний день в питоне с максимально возможным годом, когда доу даются

from datetime import datetime 

date = datetime.strptime('Wed 12 Nov', '%a %d %b') 

возвращает datetime.datetime(1900, 11, 12, 0, 0). Какой может быть лучший способ получить наибольший прошлый год ?, в этом случае должен 2014 вместо 1900.

Любая помощь будет оценена.

ответ

2

Вы можете получить год от datetime.now() и вычитать 1:

from datetime import datetime 

date = datetime.strptime('Wed 12 Nov {}'.format(datetime.now().year-1), '%a %d %b %Y') 

Это не будет работать на 29 февраля

На самом деле ошибка в первом варианте осуществления, он начинал в понедельник, потому что 12 ноябре 1900 был понедельник:

dte = 'Wed 12 Nov' 

start = datetime.strptime('Wed 12 Nov', "%a %d %b") 
greatest = None 

while start <= datetime.now(): 
    start += timedelta(days=1) 
    if start.strftime("%a %d %b") == dte: 
     greatest = start 

print(greatest) 

2014-11-12 00:00:00 

Существует также monthdelta пакет, который вы можете использовать для увеличения в месяц:

from datetime import datetime 
from monthdelta import monthdelta 


dte = 'Wed 12 Nov' 

start = datetime.strptime('Wed 12 Nov', "%a %d %b") 
greatest = None 

while start <= datetime.now(): 
    start += monthdelta(1) 
    if start.strftime("%a %d %b") == dte: 
     greatest = start 

print(greatest) 

Вы можете увидеть увеличивающиеся месяцами гораздо более эффективным:

In [1]: from datetime import datetime, timedelta 

In [2]: %%timeit 
    ...: dte = 'Wed 12 Nov' 
    ...: start = datetime.strptime('Wed 12 Nov', "%a %d %b") 
    ...: greatest = None 
    ...: while start <= datetime.now(): 
    ...:  start += timedelta(days=1) 
    ...:  if start.strftime("%a %d %b") == dte: 
    ...:   greatest = start 
    ...: 
1 loops, best of 3: 382 ms per loop 

In [3]: from datetime import datetime 

In [4]: from monthdelta import monthdelta 

In [5]: %%timeit 
    ...: dte = 'Wed 12 Nov' 
    ...: start = datetime.strptime('Wed 12 Nov', "%a %d %b") 
    ...: greatest = None 
    ...: while start <= datetime.now(): 
    ...:  start += monthdelta(1) 
    ...:  if start.strftime("%a %d %b") == dte: 
    ...:   greatest = start 
    ...: 
100 loops, best of 3: 18.7 ms per loop 

Оба возвращают довольно быстро, но если у вас было много вызовов метода, то ежемесячный рост является лучшим вариантом. Мы могли бы также добавить 30 дней, а затем установить на следующий день до 12, могут быть ошибки, как я не слишком тестировал:

def match_date(abb_wk_dy, day_date, abb_mon): 
    dte = "{} {} {}".format(abb_wk_dy.capitalize(), day_date, abb_mon.capitalize()) 
    start = datetime.strptime(dte, "%a %d %b") 
    greatest = None 
    while start <= datetime.now(): 
     start += timedelta(days=30) 
     start = start.strptime("{} {} {}".format(start.year, start.month, day_date), "%Y %m %d") 
     if start.strftime("%a %d %b") == dte: 
      greatest = start 
    return greatest 

Последний код работает довольно эффективно:

In [12]: timeit match_date("wed","12","nov") 
10 loops, best of 3: 34.7 ms per loop 

Если вы хочу только год, а затем вернуть greatest.year.

На тестировании выше код не високосные годы, поэтому мы должны поймать, что мы можем просто увеличить за год на 1 каждый раз:

def match_date(abb_wk_dy, day_date, abb_mon): 
    wkd, dd, ab = abb_wk_dy.capitalize(), day_date, abb_mon.capitalize() 
    match = "{} {} {}".format(wkd, dd, ab) 
    try: 
     dte = "{} {} {} {}".format(1900, wkd, dd, ab) 
     start = datetime.strptime(dte, "%Y %a %d %b") 
    except ValueError: 
     # first leap year since 1900 
     dte = "{} {} {} {}".format(1904, wkd, dd, ab) 
     start = datetime.strptime(dte, "%Y %a %d %b") 
    day, mon = start.day, start.month 
    greatest = None 
    while start <= datetime.now(): 
     try: 
      start = start.strptime("{} {} {}".format(start.year + 1, mon, day), "%Y %m %d") 
     except ValueError: 
      start = start.strptime("{} {} {}".format(start.year + 1, 01, 01), "%Y %m %d") 
      continue 
     if start.strftime("%a %d %b") == match: 
      greatest = start 
    return greatest.year if greatest else "No match" 

который работает в:

In [27]: timeit match_date("Wed","12","Nov") 
100 loops, best of 3: 2.63 ms per loop 

Вам также нужно будет подтвердить, что ни один день> 31 никогда не вводится, а другие месяцы и дни совпадают, что может быть достигнуто с помощью dict или calender.monthrange или максимального количества карт, отображающих максимальный день в месяц-месяц.

+0

Я думаю, что OP хочет этого, если (input_month, input_day) является * после * (today_month, today_day) - но если (input_month, input_day) уже произошло в этом году, они хотят (today_year) - но я, безусловно, читая больше в вопросе, чем было написано. – jedwards

+1

@jedwards, я думал по тем же строкам, но это не совсем ясно, простая проверка, если текущий день и месяц> затем использовать текущий год, должен работать, если это так. –

+0

Если у вас есть «Tue 12 Nov», 'вместо этого, это не сработает, потому что желаемый год будет в 2013 году. Ключ находится в день недели. –

 Смежные вопросы

  • Нет связанных вопросов^_^