上个月的python日期


131

我正在尝试使用python获取上个月的日期。这是我尝试过的:

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

但是,这种方法很糟糕,原因有两个:首先,它返回2012年2月的20122(而不是201202),其次它将返回0而不是1月的12。

我已经用bash解决了这个麻烦

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

我认为,如果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)

我没有测试过此代码,也不想使用它(除非我找不到其他方法:/)

谢谢你的帮助!


Answers:


299

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 打印。


31
您可以使用以下.replace()方法:datetime.utcnow().replace(day=1) - timedelta(days=1)
jfs

1
凉!我错过了替换方法。
bgporter 2012年

您也可以链接.replace()功能。进行一次以获得上个月,然后再次进行以获得所需的日期。首先:d = date.today() 然后one_month_ago = (d.replace(day=1) - timedelta(days=1)).replace(day=d.day)
Thane Plummer

@JFSebastian您是正确的-感谢您指出这一点。似乎没有一个优雅的线,因为“​​月”不是固定的时间段。您可以通过在2nd 中的函数中导入calendar和使用calendar.mdays[d.month-1]以及更丑陋的方式来做丑陋的事情,但是这似乎是非Python风格的,并且没有考虑到极端情况。尽管我讨厌将异常作为算法的一部分,但我更新了下面的答案,使用了所有情况下的解释。min()replacetry - except
塔娜·普鲁默

查看伊万(Ivan)的答案,并添加:min(date.today()。day,last_day_of_previous_month.day)
michel.iamit

70

您应该使用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

它不适用于一年的第一个月:>>> IllegalMonthError:不良月份号-1;必须为1-12
mtoloo

@mtoloo dateutil的什么版本?我没有这个问题,但是我将添加一些替代语法
Dave Butler 2014年

1
我喜欢这个,因为@bgporter有一个非常好的解决方案,但他的解决方案对查找下个月的效果不佳。
Daniel F

3
@mtoloo您可能输入错了月份/月份
r_black

2
@r_black是的,您是对的。那是我的错 此处给出的解决方案是正确的,并且在今年的第一个月无需进行进一步检查。
mtoloo

45
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

解决方案的一部分...要查找上个月的日期,请添加以下内容:day_previous_month = min(today.day,last_day_of_previous_month.day)以避免超过天数。
michel.iamit '16

9

bgporter的答案为基础

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

5

它非常容易和简单。做这个

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

4

对于到达这里并希望获得上个月的第一天和最后一天的人:

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

如果您想获得一个月的开始和结束时间(以及更多),请查看以下Calendar模块:stackabuse.com/introduction-to-the-python-calendar-module
toast38coza

如果要上个月的第二个月开始和结束?
游戏玩家

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

休息时间:3月31日
Mike

1

只是为了好玩,一个使用divmod的纯数学答案。由于相乘,效率很低,也可以对月份数进行简单检查(如果等于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

以@JF 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: {0}".format(one_month_ago))

输出:

one_month_ago: 2012-02-29 00:00:00

0

如果要在LINUX / UNIX环境中查看EXE类型文件中的ASCII字母,请尝试“ od -c'filename'| more”

您可能会得到很多无法识别的项目,但它们都会全部显示出来,并且将显示HEX表示形式,并且ASCII等效字符(如果适用)将跟随十六进制代码行。在您知道的已编译代码上尝试一下。您可能会在其中识别出一些东西。


您能编辑一下以解释它如何回答问题。
AdrianHHH

0

有一个高级库dateparser可以确定给定自然语言的过去日期,并返回相应的Python datetime对象

from dateparser import parse
parse('4 months ago')
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.