【问题标题】:Python : How to add month to December 2012 and get January 2013?Python:如何将月份添加到 2012 年 12 月并获得 2013 年 1 月?
【发布时间】:2012-10-04 21:25:39
【问题描述】:
>>> start_date = date(1983, 11, 23)
>>> start_date.replace(month=start_date.month+1)
datetime.date(1983, 12, 23)

这一直有效,直到月份是 <=11,只要我这样做

>>> start_date = date(1983, 12, 23)
>>> start_date.replace(month=start_date.month+1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: month must be in 1..12

当新月份添加到 12 月时,如何继续添加月份以增加年份?

【问题讨论】:

  • 它是基于玛雅历法的实现,并且试图超过 dec/2012 会溢出到周期的开始。 (抱歉不能错过这个笑话)
  • 你的笑话很糟糕,你应该感到很糟糕!
  • 如果你是在 12 月 31 日,又增加了两个月,会发生什么?你想要2月31日吗? 2 月 28 日(假设不是闰年)? 3 月 1 日?
  • 我没有想到这个,但是是的,你是对的,我应该是 3 月 1 日
  • 也就是说,您希望它是同一天,如果那一天无效,则转到下个月的第一天?

标签: python date calendar


【解决方案1】:

dateutil 库对于这样的计算很有用:

>>> start_date + relativedelta(months=2)
datetime.date(1984, 1, 23)

【讨论】:

  • 很好,不知道这个!不久前应该自己使用它而不是重新发明轮子。
  • 谢谢,如此方便和真棒,感谢您告诉@Daniel
  • 同时也发布到pip:pip install python-dateutil
【解决方案2】:

使用datetime.timedeltacalendar.monthrange

>>> from datetime import date, timedelta
>>> import calendar
>>> start_date = date(1983, 12, 23)
>>> days_in_month = calendar.monthrange(start_date.year, start_date.month)[1]
>>> start_date + timedelta(days=days_in_month)
datetime.date(1984, 1, 23)

【讨论】:

    【解决方案3】:
    try:
        start_date.replace(month=start_date.month+1)
    except ValueError:
        if start_date.month == 12:
             start_date.replace(month=1)
             start_date.replace(year=start_date.year+1)
        else:
             raise
    

    【讨论】:

      【解决方案4】:

      如果您想对此问题有更通用的解决方案,例如将天、月和年混合到一个日期:

      import time, datetime, calendar
      def upcount(dt, years=0, months=0, **kwargs):
          if months:
              total_months = dt.month + months
              month_years, months = divmod(total_months, 12)
              if months == 0:
                  month_years -= 1
                  months = 12
              years += month_years
          else:
              months = dt.month
      
          years = dt.year + years
          try:
              dt = dt.replace(year=years, month=months)
          except ValueError:
              # 31st march -> 31st april gives this error
              max_day = calendar.monthrange(years, months)[1]
              dt = dt.replace(year=years, month=months, day=max_day)
      
          if kwargs:
              dt += datetime.timedelta(**kwargs)
          return dt
      

      【讨论】:

        【解决方案5】:

        您将不得不决定如何处理奇怪的情况,例如 1 月 31 日 + 1 个月 = 2 月 31 日(不存在)。但我倾向于使用 timedelta 添加到您的日期,如下所示:

        import datetime as dt
        dt.datetime.now() + dt.timedelta(days=30)
        

        您可以根据当前或下个月的大小或其他一些值来选择天数,以免下个月溢出。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-08-20
          • 1970-01-01
          • 2020-11-11
          相关资源
          最近更新 更多