【问题标题】:how to get the same day of next month of a given day in python using datetime如何使用日期时间在python中获取给定日期的下个月的同一天
【发布时间】:2010-02-12 05:59:54
【问题描述】:

我知道使用 datetime.timedelta 我可以从给定日期中获取几天后的日期

daysafter = datetime.date.today() + datetime.timedelta(days=5)

但似乎没有datetime.timedelta(month=1)

【问题讨论】:

    标签: python datetime date


    【解决方案1】:

    使用dateutil 模块。它有relative time deltas:

    import datetime
    from dateutil import relativedelta
    nextmonth = datetime.date.today() + relativedelta.relativedelta(months=1)
    

    美丽。

    【讨论】:

    • dateutil 很棒。应该是标准的。
    • 哇,它处理 1 月 31 日 + 1 个月。它在 2 月的最后一天返回。
    • 太棒了,这就是我一直在寻找的!不过,最新的 URL 似乎是 dateutil.readthedocs.io/en/stable/index.html?如果我错了就说吧。
    • @Relaxed1 2.6.1 好像是最新版本,但是这个库已经很稳定了,似乎不需要太多更新了。
    • pip install python-dateutil
    【解决方案2】:

    当然没有——如果今天是 1 月 31 日,“下个月的同一天”会是什么?!显然没有正确解决方案,因为 2 月 31 日不存在,datetime 模块确实玩“猜猜用户在没有权利的情况下提出这个不可能的问题是什么”解决方案认为(错误地)是显而易见的解决方案”;-)。

    我建议:

    try:
      nextmonthdate = x.replace(month=x.month+1)
    except ValueError:
      if x.month == 12:
        nextmonthdate = x.replace(year=x.year+1, month=1)
      else:
        # next month is too short to have "same date"
        # pick your own heuristic, or re-raise the exception:
        raise
    

    【讨论】:

    • 谢谢亚历克斯!我曾经在 c# 中使用 Datetime.AddMonths() 来解决这个问题。所以在问转储问题之前我什至没有多想:)。我用 c# Datetime.AddMonths(1) 为 Jan (28-31) 做了一个测试,有趣的结果,我得到了 28 年 2 月 5 日。再次感谢 Alex!
    【解决方案3】:

    您可以使用calendar.nextmonth(来自Python 3.7)。

    >>> import calendar
    >>> calendar.nextmonth(year=2019, month=6)
    (2019, 7)
    >>> calendar.nextmonth(year=2019, month=12)
    (2020, 1)
    

    但请注意,此函数不是公共 API,它在 calendar.Calendar.itermonthdays3() 方法内部使用。这就是它不检查给定月份值的原因:

    >>> calendar.nextmonth(year=2019, month=60)
    (2019, 61)
    

    Python 3.8 中已经实现为内部函数。

    【讨论】:

      【解决方案4】:
      from calendar import mdays
      from datetime import datetime, timedelta
      
      today = datetime.now()
      next_month_of_today = today + timedelta(mdays[today.month])
      

      我不想导入 dateutil。试试这个。祝你好运。

      【讨论】:

      • 我真的希望这个解决方案能够工作,但是使用 mdays 将打破 2 月 4 日的一年...
      • mdays 甚至没有在文档中公开,可能是因为 mdays 对于闰年不准确。 'monthrange' 函数更准确,因为它考虑到了这一点。
      【解决方案5】:
      import calendar, datetime
      
      def next_month ( date ):
          """return a date one month in advance of 'date'. 
          If the next month has fewer days then the current date's month, this will return an
          early date in the following month."""
          return date + datetime.timedelta(days=calendar.monthrange(date.year,date.month)[1])
      

      【讨论】:

      • 这是错误的。 next_month(datetime.date(2014,01,30)) == datetime.date(2014, 3, 2)
      【解决方案6】:

      这对我有用

      import datetime
      import calendar
      
      
      def next_month_date(d):
          _year = d.year+(d.month//12)
          _month =  1 if (d.month//12) else d.month + 1
          next_month_len = calendar.monthrange(_year,_month)[1]
          next_month = d
          if d.day > next_month_len:
              next_month = next_month.replace(day=next_month_len)
          next_month = next_month.replace(year=_year, month=_month)
          return next_month
      

      用法:

      d = datetime.datetime.today()
      print next_month_date(d)
      

      【讨论】:

        【解决方案7】:
        from datetime import timedelta
        try:
            next_month = (x.replace(day=28) + timedelta(days=7)).replace(day=x.day)
        except ValueError:  # assuming January 31 should return last day of February.
            next_month = (x + timedelta(days=31)).replace(day=1) - timedelta(days=1)
        

        【讨论】:

          【解决方案8】:

          我就是这样解决的。

          from datetime import datetime, timedelta
          from calendar import monthrange
          
          today_date = datetime.now().date()  # 2021-10-29
          year = today_date.year
          month = today_date.month
          
          days_in_month = monthrange(year, month)[1]
          next_month = today_date + timedelta(days=days_in_month)
          print(next_month)  # 2021-11-29
          

          【讨论】:

            【解决方案9】:

            我就是这样解决的。

            from datetime import date
            try:
                (year, month) = divmod(date.today().month, 12)
                next_month = date.today().replace(year=date.today().year+year, month=month+1)
            except ValueError:
                # This day does not exist in next month
            

            如果你只想要下个月的第一天,你可以通过设置replace(year=date.today().year+year, month=month, day=1)跳过try/catch。这将始终是一个有效的日期,因为我们已经使用 divmod 捕获了月份溢出。

            【讨论】:

              【解决方案10】:

              添加月份时,我经常需要将日期保留为最后一个月。我尝试将月份数量添加到后一天,然后再次删除一天。如果失败,我会再增加一天,直到成功。

              from datetime import timedelta
              
              DAY = timedelta(1)
              
              def add_months(d, months):
                  "Add months to date and retain last day in month."
                  d += DAY
                  # calculate year diff and zero based month
                  y, m = divmod(d.month + months - 1, 12)
                  try:
                      return d.replace(d.year + y, m + 1) - DAY
                  except ValueError:
                      # on fail return last day in month
                      # can't fail on december so just adding one more month
                      return d.replace(d.year + y, m + 2, 1) - DAY
              

              【讨论】:

                【解决方案11】:

                没有额外模块或内部函数的 Python3 解决方案。

                from datetime import date
                today = date.today()
                nextMonth = date(today.year+((today.month+1)//12) , ((today.month+1)%12), today.day)
                

                整数代数万岁!

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 2013-03-04
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2021-10-26
                  • 2020-12-18
                  • 1970-01-01
                  相关资源
                  最近更新 更多