【问题标题】:Add one year in current date PYTHON在当前日期添加一年 PYTHON
【发布时间】:2013-03-22 10:04:20
【问题描述】:

我从 database 中提取了一个 date,其中包含以下 variable

{{ i.operation_date }}

我得到了像

这样的值
April 1, 2013

我需要在上面加上一年,这样我才能得到

April 1, 2014

请建议,我该怎么做?

【问题讨论】:

标签: python date


【解决方案1】:

您可以将日期中的年份替换为预期的结果

import datetime
date_now = datetime.date.today()
years_to_add = date_now.year + 1

date_1 = date_now.strftime('%Y-%m-%d')
date_2 = date_now.replace(year=years_to_add).strftime('%Y-%m-%d')

print(date_1)
print(date_2)

# 2021-08-03
# 2022-08-03

【讨论】:

  • 已经有很多很好的答案了,不知道这个是否真的给问题增加了什么。
【解决方案2】:

这是我发现的另一个非常简洁且不使用外部包的答案:

import datetime as dt
import calendar

# Today, in `dt.date` type
day = dt.datetime.now().date()

one_year_delta = dt.timedelta(days=366 if ((day.month >= 3 and calendar.isleap(day.year+1)) or
                                            (day.month < 3 and calendar.isleap(day.year))) else 365)

# Add one year to the current date
print(day + one_year_delta)

【讨论】:

    【解决方案3】:

    另一种方法是使用 pandas "DateOffset" 类

    链接:-https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.tseries.offsets.DateOffset.html

    使用 ASGM 的代码(在答案中):

    from datetime import datetime
    import pandas as pd
    
    your_date_string = "April 1, 2012"
    format_string = "%B %d, %Y"
    
    datetime_object = datetime.strptime(your_date_string, format_string).date()
    new_date = datetime_object + pd.DateOffset(years=1)
    
    new_date.date()
    

    它将返回带有添加年份的日期时间对象。

    类似这样的:-

    datetime.date(2013, 4, 1)
    

    【讨论】:

      【解决方案4】:

      您可以使用Python-dateutil's relativedelta 来增加datetime 对象,同时保持对闰年和月份长度等内容的敏感度。 Python-dateutil 与 matplotlib 一起打包,如果你已经有的话。您可以执行以下操作:

      from dateutil.relativedelta import relativedelta
      
      new_date = old_date + relativedelta(years=1)
      

      (此答案由@Max 提供给similar question)。

      但如果您的日期是一个字符串(即还不是datetime 对象),您可以使用datetime 对其进行转换:

      from datetime import datetime
      from dateutil.relativedelta import relativedelta
      
      your_date_string = "April 1, 2012"
      format_string = "%B %d, %Y"
      
      datetime_object = datetime.strptime(your_date_string, format_string).date()
      new_date = datetime_object + relativedelta(years=1)
      new_date_string = datetime.strftime(new_date, format_string).replace(' 0', ' ')
      

      new_date_string 将包含“2013 年 4 月 1 日”。

      注意:不幸的是,datetime 仅将日期值输出为“十进制数字” - 即,如果它们是单个数字,则带有前导零。最后的.replace() 是处理从@Alex Martelli 复制的此问题的解决方法(请参阅this question 了解他和其他解决此问题的方法)。

      【讨论】:

        【解决方案5】:

        AGSM's answer 显示了使用python-dateutil 包解决此问题的便捷方法。但是,如果您不想安装该软件包怎么办?你可以像这样在原版 Python 中解决这个问题:

        from datetime import date
        
        def add_years(d, years):
            """Return a date that's `years` years after the date (or datetime)
            object `d`. Return the same calendar date (month and day) in the
            destination year, if it exists, otherwise use the following day
            (thus changing February 29 to March 1).
        
            """
            try:
                return d.replace(year = d.year + years)
            except ValueError:
                return d + (date(d.year + years, 1, 1) - date(d.year, 1, 1))
        

        如果您想要另一种可能性(将 2 月 29 日更改为 2 月 28 日),那么最后一行应更改为:

                return d + (date(d.year + years, 3, 1) - date(d.year, 3, 1))
        

        【讨论】:

        • 正确,希望他们补充。
        • 答案不同:relativedelta() 保留当月的最后一天,即date(2016, 2, 29) + relativedelta(years=1) == date(2017, 2, 28)。您的解决方案在下个月的第一天产生(如记录):add_years(date(2016,2,29), 1) == date(2017, 3, 1)
        • 如何将最后一行更改为:return date(d.year + years, 3, 1)。这样更容易阅读。
        • 这个怎么用?
        【解决方案6】:

        当我需要添加几个月或几年并且不想导入更多库时,我会这样做。 只需创建一个 datetime.date() 对象,调用 add_month(date) 添加一个月,调用 add_year(date) 添加一年。

        import datetime
        __author__ = 'Daniel Margarido'
        
        
        # Check if the int given year is a leap year
        # return true if leap year or false otherwise
        def is_leap_year(year):
            if (year % 4) == 0:
                if (year % 100) == 0:
                    if (year % 400) == 0:
                        return True
                    else:
                        return False
                else:
                    return True
            else:
                return False
        
        
        THIRTY_DAYS_MONTHS = [4, 6, 9, 11]
        THIRTYONE_DAYS_MONTHS = [1, 3, 5, 7, 8, 10, 12]
        
        # Inputs -> month, year Booth integers
        # Return the number of days of the given month
        def get_month_days(month, year):
            if month in THIRTY_DAYS_MONTHS:   # April, June, September, November
                return 30
            elif month in THIRTYONE_DAYS_MONTHS:   # January, March, May, July, August, October, December
                return 31
            else:   # February
                if is_leap_year(year):
                    return 29
                else:
                    return 28
        
        # Checks the month of the given date
        # Selects the number of days it needs to add one month
        # return the date with one month added
        def add_month(date):
            current_month_days = get_month_days(date.month, date.year)
            next_month_days = get_month_days(date.month + 1, date.year)
        
            delta = datetime.timedelta(days=current_month_days)
            if date.day > next_month_days:
                delta = delta - datetime.timedelta(days=(date.day - next_month_days) - 1)
        
            return date + delta
        
        
        def add_year(date):
            if is_leap_year(date.year):
                delta = datetime.timedelta(days=366)
            else:
                delta = datetime.timedelta(days=365)
        
            return date + delta
        
        
        # Validates if the expected_value is equal to the given value
        def test_equal(expected_value, value):
            if expected_value == value:
                print "Test Passed"
                return True
        
            print "Test Failed : " + str(expected_value) + " is not equal to " str(value)
            return False
        
        # Test leap year
        print "---------- Test leap year ----------"
        test_equal(True, is_leap_year(2012))
        test_equal(True, is_leap_year(2000))
        test_equal(False, is_leap_year(1900))
        test_equal(False, is_leap_year(2002))
        test_equal(False, is_leap_year(2100))
        test_equal(True, is_leap_year(2400))
        test_equal(True, is_leap_year(2016))
        
        # Test add month
        print "---------- Test add month ----------"
        test_equal(datetime.date(2016, 2, 1), add_month(datetime.date(2016, 1, 1)))
        test_equal(datetime.date(2016, 6, 16), add_month(datetime.date(2016, 5, 16)))
        test_equal(datetime.date(2016, 3, 15), add_month(datetime.date(2016, 2, 15)))
        test_equal(datetime.date(2017, 1, 12), add_month(datetime.date(2016, 12, 12)))
        test_equal(datetime.date(2016, 3, 1), add_month(datetime.date(2016, 1, 31)))
        test_equal(datetime.date(2015, 3, 1), add_month(datetime.date(2015, 1, 31)))
        test_equal(datetime.date(2016, 3, 1), add_month(datetime.date(2016, 1, 30)))
        test_equal(datetime.date(2016, 4, 30), add_month(datetime.date(2016, 3, 30)))
        test_equal(datetime.date(2016, 5, 1), add_month(datetime.date(2016, 3, 31)))
        
        # Test add year
        print "---------- Test add year ----------"
        test_equal(datetime.date(2016, 2, 2), add_year(datetime.date(2015, 2, 2)))
        test_equal(datetime.date(2001, 2, 2), add_year(datetime.date(2000, 2, 2)))
        test_equal(datetime.date(2100, 2, 2), add_year(datetime.date(2099, 2, 2)))
        test_equal(datetime.date(2101, 2, 2), add_year(datetime.date(2100, 2, 2)))
        test_equal(datetime.date(2401, 2, 2), add_year(datetime.date(2400, 2, 2)))
        

        【讨论】:

        • add_year 如果是一圈年并且您的日期是三月或之后,则效果不佳。换句话说,这个测试失败了:test_equal(datetime.date(2021, 4, 2), add_year(datetime.date(2020, 4, 2)))
        • 另外:一圈前一年也会失败:这个测试也失败了:test_equal(datetime.date(2020, 4, 2), add_year(datetime.date(2019, 4, 2)))
        【解决方案7】:

        看看这个:

        #!/usr/bin/python
        
        import datetime
        
        def addYears(date, years):
            result = date + datetime.timedelta(366 * years)
            if years > 0:
                while result.year - date.year > years or date.month < result.month or date.day < result.day:
                    result += datetime.timedelta(-1)
            elif years < 0:
                while result.year - date.year < years or date.month > result.month or date.day > result.day:
                    result += datetime.timedelta(1)
            print "input: %s output: %s" % (date, result)
            return result
        

        示例用法:

        addYears(datetime.date(2012,1,1), -1)
        addYears(datetime.date(2012,1,1), 0)
        addYears(datetime.date(2012,1,1), 1)
        addYears(datetime.date(2012,1,1), -10)
        addYears(datetime.date(2012,1,1), 0)
        addYears(datetime.date(2012,1,1), 10)
        

        这个例子的输出:

        input: 2012-01-01 output: 2011-01-01
        input: 2012-01-01 output: 2012-01-01
        input: 2012-01-01 output: 2013-01-01
        input: 2012-01-01 output: 2002-01-01
        input: 2012-01-01 output: 2012-01-01
        input: 2012-01-01 output: 2022-01-01
        

        【讨论】:

          【解决方案8】:

          如果还没有,请将其转换为 python 日期时间对象。然后添加增量时间

          one_years_later = Your_date + datetime.timedelta(days=(years*days_per_year)) 
          

          为您的案例天数=365。

          您可以有条件检查年份是否为闰年并相应调整天数

          您可以添加任意年数

          【讨论】:

          • -1 因为闰年:date(2012, 1, 1) + timedelta(days=365)date(2012, 12, 31)
          【解决方案9】:

          从您的问题看来,您只想简单地增加给定日期的年份,而不是担心闰年的影响。您可以使用日期类通过访问其成员年份来执行此操作。

          from datetime import date
          startDate = date(2012, 12, 21)
          
          # reconstruct date fully
          endDate = date(startDate.year + 1, startDate.month, startDate.day)
          # replace year only
          endDate = startDate.replace(startDate.year + 1)
          

          如果您在创建给定格式时遇到问题,请告诉我们。

          【讨论】:

          • @AntonyHatchkins:你能解释一下为什么这个答案中的代码很差吗?在我看来是对的。
          • z = datetime(2012,02,29); z.replace(z.year+1) -> ValueError: day is out of range for month
          • z + relativedelta(years=1) -> datetime.datetime(2013, 2, 28, 0, 0)
          • @AntonyHatchkins:不错的收获。
          猜你喜欢
          • 2020-11-11
          • 1970-01-01
          • 1970-01-01
          • 2020-04-04
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多