Python начало прошлого месяца

дата python предыдущего месяца

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

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

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

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

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

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) 

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

9 ответов

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 >>> 

вы должны использовать 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 
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 
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')) 

его очень легко и просто. Сделай это!--3-->

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 
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)) 

просто для удовольствия, чистый математический ответ с использованием 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 
import datetime today = datetime.date.today() last_month = today.replace(month=today.month-1, day=1) 

основываясь на комментарии @J. F. Sebastian, вы можете связать 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: ".format(one_month_ago)) 
one_month_ago: 2012-02-29 00:00:00 

Источник

python date of the previous month

However, this way is bad for 2 reasons: First it returns 20122 for the February of 2012 (instead of 201202) and secondly it will return 0 instead of 12 on January. I have solved this trouble in bash with

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

I think that if bash has a built-in way for this purpose, then python, much more equipped, should provide something better than forcing writing one's own script to achieve this goal. Of course i could do something like:

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) 

I have not tested this code and i don't want to use it anyway (unless I can't find any other way:/) Thanks for your help!

18 Answers 18

datetime and the datetime.timedelta classes are your friend.

  1. find today.
  2. use that to find the first day of this month.
  3. use timedelta to backup a single day, to the last day of the previous month.
  4. print the YYYYMM string you're looking for.
 import datetime today = datetime.date.today() first = today.replace(day=1) last_month = first - datetime.timedelta(days=1) print(last_month.strftime("%Y%m")) 

You can also chain the .replace() function. Do it once to get the last month, then do it again to get the day you want. First: d = date.today() then one_month_ago = (d.replace(day=1) - timedelta(days=1)).replace(day=d.day)

@J.F.Sebastian You are correct -- thanks for pointing that out. There doesn't seem to be an elegant one-liner for this as a "month" is not a constant time period. You can do something ugly by importing calendar and using calendar.mdays[d.month-1] and more ugliness in a min() function in the 2nd replace , but it seems un-Pythonic and doesn't account for corner cases. I've updated my answer below using try - except which accounts for all cases, although a I hate using exceptions as part of an algorithm.

You should use dateutil. With that, you can use relativedelta, it's an improved version of 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 

It's not working for the first month of year: >>> IllegalMonthError: bad month number -1; must be 1-12

I prefer this one because while @bgporter has a very nice solution, his one doesn't work as nice for looking up the next month.

@r_black Yes You are right. That was my fault. Solution given here is correct and no further check is needed for the first month of the year.

Note that if the previous month's date doesn't exist (e.g. October 31st exists, but September 31st does not exist), then relativedelta will use the next older day (e.g. September 30th)

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 

part of the solution. to find the day of last month, add something like this: day_previous_month = min(today.day, last_day_of_previous_month.day) to avoid exceeding the number of days.

#one line formated to YYYYMM 'from datetime import date, timedelta ANOMES = (date.today().replace(day=1) - timedelta(days=1)).strftime("%Y%m")'

For someone who got here and looking to get both the first and last day of the previous month:

from datetime import date, timedelta last_day_of_prev_month = date.today().replace(day=1) - timedelta(days=1) start_day_of_prev_month = date.today().replace(day=1) - timedelta(days=last_day_of_prev_month.day) # For printing results print("First day of prev month:", start_day_of_prev_month) print("Last day of prev month:", last_day_of_prev_month) 
First day of prev month: 2019-02-01 Last day of prev month: 2019-02-28 

If you want to get the start and end of a month (and more), have a look at the Calendar module: stackabuse.com/introduction-to-the-python-calendar-module

You are a saviour! I was fiddling with calendar, dateutil with my soggy brain. But this is much better. Thank you!

Simple, one liner:

import datetime as dt previous_month = (dt.date.today().replace(day=1) - dt.timedelta(days=1)).month 

Its very easy and simple. Do this

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() 

Here is the output: $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 
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')) 

With the Pendulum very complete library, we have the subtract method (and not "subStract"):

import pendulum today = pendulum.datetime.today() # 2020, january lastmonth = today.subtract(months=1) lastmonth.strftime('%Y%m') # '201912' 

We see that it handles jumping years.

The reverse equivalent is add .

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)) 
import datetime result = (datetime.datetime.today().month - 2) % 12 + 1 

The problem is how to transfer month [1, 2, 3, . 12] to [12, 1, 2, . 11].

Step1: month = month - 1 transfer [1, 2, 3, . 12] to [0, 1, 2, . 11].

Step2: month = (month - 1) % 12 transfer [0, 1, 2, . 11] to [11, 0, 1, . 10].

Step3: month = month + 1 transfer [11, 0, 1, . 10] to [12, 1, 2, . 11].

So, the result is result = (month - 2) % 12 + 1

Just for fun, a pure math answer using divmod. Pretty inneficient because of the multiplication, could do just as well a simple check on the number of month (if equal to 12, increase year, etc)

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 

There is a high level library dateparser that can determine the past date given natural language, and return the corresponding Python datetime object

from dateparser import parse parse('4 months ago') 

You might have come here because you're working with Jython in NiFi. This is how I ended up implementing it. I deviated a little from this answer by Robin Carlo Catacutan because accessing last_day_of_prev_month.day wasn't possible due to a Jython datatype issue explained here that for some reason seems to exist in NiFi'S Jython but not in vanilla Jython.

from datetime import date, timedelta import calendar flowFile = session.get() if flowFile != None: first_weekday_in_prev_month, num_days_in_prev_month = calendar.monthrange(date.today().year,date.today().month-1) last_day_of_prev_month = date.today().replace(day=1) - timedelta(days=1) first_day_of_prev_month = date.today().replace(day=1) - timedelta(days=num_days_in_prev_month) last_day_of_prev_month = str(last_day_of_prev_month) first_day_of_prev_month = str(first_day_of_prev_month) flowFile = session.putAllAttributes(flowFile, < "last_day_of_prev_month": last_day_of_prev_month, "first_day_of_prev_month": first_day_of_prev_month >) session.transfer(flowFile, REL_SUCCESS) 

Источник

Читайте также:  Java server vm default
Оцените статью