2012-03-15 4 views
60

Я пытаюсь получить дату предыдущего месяца с помощью python. Вот что я пробовал:python дата предыдущего месяца

str(time.strftime('%Y')) + str(int(time.strftime('%m'))-1) 

Однако этот путь плох по 2 причинам: во-первых она возвращает 20122 за февраль 2012 года (вместо 201202) и во-вторых, она возвращает 0 вместо 12 на январь.

Я решил эту проблемы в Баш с

echo $(date -d"3 month ago" "+%G%m%d") 

Я думаю, что если Баш имеет встроенный способ для этой цели, то питон, гораздо более подготовлены, должны предоставить что-то лучше, чем принуждение писать свою собственную сценарий для достижения этой цели. Конечно, я мог бы сделать что-то вроде:

if int(time.strftime('%m')) == 1: 
    return '12' 
else: 
    if int(time.strftime('%m')) < 10: 
     return '0'+str(time.strftime('%m')-1) 
    else: 
     return str(time.strftime('%m') -1) 

Я не проверял этот код и я не хочу, так или иначе использовать его (если я не могу найти какой-либо другой путь: /)

Спасибо за ваша помощь!

+1

Это Python 2 или 3? –

+1

: [Самый простой способ вычесть месяц со дня на Python?] (Http://stackoverflow.com/a/7153449/4279) – jfs

ответ

158

datetime и классы datetime.timedelta ваш друг.

  1. найти сегодня.
  2. использовать это, чтобы найти первый день этого месяца.
  3. использовать timedelta для резервного копирования на один день, до последнего дня предыдущего месяца.
  4. напечатайте строку YYYYMM, которую вы ищете.

Как это:

>>> import datetime 
>>> today = datetime.date.today() 
>>> first = today.replace(day=1) 
>>> lastMonth = first - datetime.timedelta(days=1) 
>>> print lastMonth.strftime("%Y%m") 
201202 
>>> 
+16

вы можете использовать метод '.replace()': datetime.utcnow(). Replace (day = 1) - timedelta (days = 1) ' – jfs

+0

Прохладный! Я пропустил метод замены. – bgporter

+0

Вы также можете связать функцию '.replace()'. Сделайте это один раз, чтобы получить последний месяц, затем сделайте это снова, чтобы получить тот день, который вы хотите. Сначала: 'd = date.today()' then' one_month_ago = (d.replace (день = 1) - timedelta (days = 1)). Replace (day = d.day) ' –

37

Вы должны использовать dateutil. С этим вы можете использовать relativedelta, это улучшенная версия timedelta.

>>> import datetime 
>>> import dateutil.relativedelta 
>>> now = datetime.datetime.now() 
>>> print now 
2012-03-15 12:33:04.281248 
>>> print now + dateutil.relativedelta.relativedelta(months=-1) 
2012-02-15 12:33:04.281248 
+0

Он не работает в течение первого месяца года: >>> IllegalMonthError : неправильный номер месяца -1; должно быть 1-12 – mtoloo

+0

@mtoloo Какая версия даты? У меня нет этой проблемы, но я добавлю альтернативный синтаксис. –

+0

Я предпочитаю этот вариант, потому что в то время как @bgporter имеет очень приятное решение, он не работает так хорошо, как смотреть в следующем месяце. –

5

Строительство на bgporter's answer.

def prev_month_range(when = None): 
    """Return (previous month's start date, previous month's end date).""" 
    if not when: 
     # Default to today. 
     when = datetime.datetime.today() 
    # Find previous month: https://stackoverflow.com/a/9725093/564514 
    # Find today. 
    first = datetime.date(day=1, month=when.month, year=when.year) 
    # Use that to find the first day of this month. 
    prev_month_end = first - datetime.timedelta(days=1) 
    prev_month_start = datetime.date(day=1, month= prev_month_end.month, year= prev_month_end.year) 
    # Return previous month's start and end dates in YY-MM-DD format. 
    return (prev_month_start.strftime('%Y-%m-%d'), prev_month_end.strftime('%Y-%m-%d')) 
33
from datetime import date, timedelta 

first_day_of_current_month = date.today().replace(day=1) 
last_day_of_previous_month = first_day_of_current_month - timedelta(days=1) 

print "Previous month:", last_day_of_previous_month.month 

Или:

from datetime import date, timedelta 

prev = date.today().replace(day=1) - timedelta(days=1) 
print prev.month 
+0

часть решения ... чтобы найти день последнего месяца, добавьте что-то вроде этого: day_previous_month = min (today.day, last_day_of_previous_month.day), чтобы избежать превышения количества дней. –

1

Просто для удовольствия, чистая математика ответ, используя divmod. Довольно inneficient из-за умножения, может сделать так же, простая проверка на количество месяцев (если равен 12, увеличение год, и т.д.)

year = today.year 
month = today.month 

nm = list(divmod(year * 12 + month + 1, 12)) 
if nm[1] == 0: 
    nm[1] = 12 
    nm[0] -= 1 
pm = list(divmod(year * 12 + month - 1, 12)) 
if pm[1] == 0: 
    pm[1] = 12 
    pm[0] -= 1 

next_month = nm 
previous_month = pm 
0

Строительство от замечание @ J.F. Себастьян, вы можете связать функцию replace(), чтобы вернуться на один «месяц». Поскольку месяц не является постоянным периодом времени, это решение пытается вернуться к той же дате в предыдущем месяце, что, конечно же, не работает в течение всех месяцев. В этом случае этот алгоритм по умолчанию используется для последнего дня предыдущего месяца.

from datetime import datetime, timedelta 

d = datetime(2012, 3, 31) # A problem date as an example 

# last day of last month 
one_month_ago = (d.replace(day=1) - timedelta(days=1)) 
try: 
    # try to go back to same day last month 
    one_month_ago = one_month_ago.replace(day=d.day) 
except ValueError: 
    pass 
print("one_month_ago: {0}".format(one_month_ago)) 

Выход:

one_month_ago: 2012-02-29 00:00:00 
2
def prev_month(date=datetime.datetime.today()): 
    if date.month == 1: 
     return date.replace(month=12,year=date.year-1) 
    else: 
     try: 
      return date.replace(month=date.month-1) 
     except ValueError: 
      return prev_month(date=date.replace(day=date.day-1)) 
1

Его очень легко и просто. Сделайте это

from dateutil.relativedelta import relativedelta 
from datetime import datetime 

today_date = datetime.today() 
print "todays date time: %s" %today_date 

one_month_ago = today_date - relativedelta(months=1) 
print "one month ago date time: %s" % one_month_ago 
print "one month ago date: %s" % one_month_ago.date() 

Вот результат: $ python2.7 main.py

todays date time: 2016-09-06 02:13:01.937121 
one month ago date time: 2016-08-06 02:13:01.937121 
one month ago date: 2016-08-06 
0

Это работает для меня:

import datetime 
today = datetime.date.today() 
last_month = today.replace(month=today.month-1, day=1) 
+4

Вы, наверное, не пробовали это в январе. – pdw

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