在当前日期PYTHON中添加一年

时间:2013-04-01 10:19:57

标签: python date

我从数据获取日期,其中包含以下变量

{{ i.operation_date }}

我得到了像

这样的值
April 1, 2013

我需要在上面添加一年,以便我可以

April 1, 2014

请建议,我该怎么做?

9 个答案:

答案 0 :(得分:95)

AGSM's answer显示了使用python-dateutil包解决此问题的便捷方法。但是,如果您不想安装该软件包呢?您可以像这样解决vanilla 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))

答案 1 :(得分:44)

您可以使用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了解此问题的其他方法)。

答案 2 :(得分: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)

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

答案 3 :(得分:2)

当我需要添加数月或数年并且不想导入更多库时,我就会这样做。 只需创建一个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)))

答案 4 :(得分: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)

答案 5 :(得分:1)

另一种方法是使用熊猫“ 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对象。

类似这样的东西:-

datetime.date(2013, 4, 1)

答案 6 :(得分:0)

看看这个:

#!/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

答案 7 :(得分:-1)

如果它还没有,则将其转换为python datetime对象。然后添加deltatime

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

您的案例天= 365。

您可以有条件检查年份是否跳跃或相应调整日期

您可以根据需要添加多年

答案 8 :(得分:-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