【问题标题】:python date of the previous month上个月的python日期
【发布时间】:2012-04-01 06:23:48
【问题描述】:

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

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

但是,这种方式不好有两个原因:首先它会在 2012 年 2 月返回 20122(而不是 201202),其次它将在 1 月返回 0 而不是 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)

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

感谢您的帮助!

【问题讨论】:

标签: python date time


【解决方案1】:
import pandas as pd

lastmonth = int(pd.to_datetime("today").strftime("%Y%m"))-1

print(lastmonth)

202101

from datetime import date, timedelta
YYYYMM = (date.today().replace(day=1)-timedelta(days=1)).strftime("%Y%m")

【讨论】:

  • 这不适用于每年的一月:(202201 - 1) = 202200!!!
【解决方案2】:

你可以这样做:

from datetime import datetime, timedelta    
last_month = (datetime.now() - timedelta(days=32)).strftime("%Y%m")

【讨论】:

    【解决方案3】:

    您可能来到这里是因为您正在使用 NiFi 中的 Jython。这就是我最终实现它的方式。我与this answer by Robin Carlo Catacutan 略有偏差,因为由于 Jython 数据类型问题解释了 here,因此无法访问 last_day_of_prev_month.day,由于某种原因,该问题似乎存在于 NiFi 的 Jython 中,但不存在于原版 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)
    

    【讨论】:

      【解决方案4】:

      简单,一个班轮:

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

      【讨论】:

        【解决方案5】:

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

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

        【讨论】:

          【解决方案6】:

          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 被打印出来。

          【讨论】:

          • 你可以使用.replace()方法:datetime.utcnow().replace(day=1) - timedelta(days=1)
          • 酷!我错过了替换方法。
          • 你也可以链接.replace()函数。做一次以获得最后一个月,然后再做一次以获得你想要的那一天。首先:d = date.today() 然后one_month_ago = (d.replace(day=1) - timedelta(days=1)).replace(day=d.day)
          • @J.F.Sebastian 你是对的——感谢您指出这一点。似乎没有一个优雅的单线,因为“​​月”不是一个恒定的时间段。你可以通过导入calendar 并在第二个replacemin() 函数中使用calendar.mdays[d.month-1] 和更多丑陋来做一些丑陋的事情,但它似乎不是Pythonic 并且不考虑极端情况。我在下面使用try - except 更新了我的答案,它适用于所有情况,尽管我讨厌将异常用作算法的一部分。
          • 看Ivan的回答,加上:min(date.today().day, last_day_of_previous_month.day)
          【解决方案7】:

          有了Pendulum 非常完整的库,我们就有了subtract 方法(而不是“subStract”):

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

          我们看到它可以处理跳跃的年份。

          反向等效是add

          https://pendulum.eustace.io/docs/#addition-and-subtraction

          【讨论】:

            【解决方案8】:

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

            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
            

            【讨论】:

            【解决方案9】:

            您应该使用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: bad month number -1;必须是 1-12
            • 我更喜欢这个,因为虽然@bgporter 有一个非常好的解决方案,但他的解决方案在下个月查找时效果不佳。
            • @mtoloo 你可能打错了几个月/月
            • @r_black 是的,你是对的。那是我的错。此处给出的解决方案是正确的,一年中的第一个月不需要进一步检查。
            • 请注意,如果上个月的日期不存在(例如 10 月 31 日存在,但 9 月 31 日不存在),则 relativedelta 将使用下一个较早的日期(例如 9 月 30 日)
            【解决方案10】:

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

            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
            

            【讨论】:

              【解决方案11】:
              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 日休息
              【解决方案12】:

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

              输出:

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

              【讨论】:

                【解决方案13】:

                只是为了好玩,使用 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
                

                【讨论】:

                  【解决方案14】:
                  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) 以避免超过天数。跨度>
                  • #one line formated to YYYYMM 'from datetime import date, timedelta ANOMES = (date.today().replace(day=1) - timedelta(days=1)).strftime("%Y %m")'
                  【解决方案15】:

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

                  【讨论】:

                    猜你喜欢
                    • 1970-01-01
                    • 1970-01-01
                    • 2018-02-17
                    • 1970-01-01
                    • 2014-02-05
                    • 1970-01-01
                    • 1970-01-01
                    • 2021-06-11
                    • 2010-12-01
                    相关资源
                    最近更新 更多