web-dev-qa-db-fra.com

Ajouter une année dans la date actuelle PYTHON

J'ai récupéré un date de base de données avec le suivant variable

{{ i.operation_date }}

avec lequel j'ai eu une valeur comme

April 1, 2013

J'ai besoin d'ajouter un an à ce qui précède pour pouvoir obtenir

April 1, 2014

S'il vous plaît suggérer, comment puis-je faire cela?

48
user2106353

réponse de AGSM montre un moyen pratique de résoudre ce problème en utilisant le python-dateutil paquet. Mais que faire si vous ne voulez pas installer ce paquet? Vous pouvez résoudre le problème dans Vanilla Python comme ceci:

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

Si vous voulez l’autre possibilité (changer du 29 au 28 février), la dernière ligne doit être remplacée par:

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

Vous pouvez utiliser Python-dateutil'srelativedelta pour incrémenter un objet datetime tout en restant sensible aux choses telles que les années bissextiles et les longueurs mensuelles. Python-dateutil est livré avec matplotlib si vous en avez déjà un. Vous pouvez faire ce qui suit:

from dateutil.relativedelta import relativedelta

new_date = old_date + relativedelta(years=1)

(Cette réponse a été donnée par @Max à un question similaire ).

Mais si votre date est une chaîne (c’est-à-dire pas déjà un objet datetime), vous pouvez la convertir en utilisant date/heure :

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 Contiendra "1er avril 2013".

NB: Malheureusement, datetime ne renvoie que les valeurs de jour sous forme de "nombres décimaux" - c’est-à-dire avec les zéros non significatifs s’il s’agit de nombres à un chiffre. La .replace() à la fin est une solution de contournement pour résoudre ce problème, copiée à partir de @Alex Martelli (voir cette question pour son approche et d'autres solutions à ce problème).

46
ASGM

D'après votre question, il semble que vous voudriez simplement incrémenter l'année de votre date donnée plutôt que de vous inquiéter des implications pour les années bissextiles. Pour ce faire, vous pouvez utiliser la classe de date en accédant à son année de membre.

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)

Si vous rencontrez des problèmes pour en créer un compte tenu de votre format, faites-le nous savoir.

9
DrCurrency

C'est ce que je fais quand j'ai besoin d'ajouter des mois ou des années et que je ne veux pas importer plus de bibliothèques. Créez simplement un objet datetime.date (), appelez add_month (date) pour ajouter un mois et add_year (date) pour ajouter une année.

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)))
2
Daniel Margarido

Une autre solution consisterait à utiliser la classe pandas "DateOffset"

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

En utilisant le code ASGM (ci-dessus dans les réponses):

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

Il renverra l'objet datetime avec l'année ajoutée.

Quelque chose comme ça:-

datetime.date(2013, 4, 1)
1
Siddharth

Regarde ça:

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

Exemple d'utilisation:

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)

Et sortie de cet exemple:

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
0
ArkadiuszG