2013-04-01 4 views
36

Я принес дату из базы данных со следующим переменнойДобавить один год в текущей дате PYTHON

{{ i.operation_date }} 

, с которым я получил значение как

April 1, 2013 

мне нужно добавить один год к вышеуказанному, чтобы я мог получить

April 1, 2014 

Пожалуйста, предложите, как я могу это сделать?

+4

[Что вы пробовали?] (Http://mattgemmell.com/2008/12/08/what-have-you-tried/) –

+0

Если вы хотите сделать это в шаблонах только тогда см. этот http://stackoverflow.com/questions/10715253/display-timestamp-in-django-template. Теперь вы можете написать тег шаблона, который может добавить один год к текущему значению. –

+0

: [Как конвертировать лет в секунду] (http://stackoverflow.com/a/32658742/4279) – jfs

ответ

-1

преобразуйте его в объект datetime python, если он еще не установлен. затем добавить deltatime

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

для вашего случая дней = 365.

вы можете иметь условие, чтобы проверить, если год високосный или нет и корректировать дней соответственно

вы можете добавить столько лет, сколько вы хотите

+4

-1 из-за високосных лет: 'date (2012, 1, 1) + timedelta (days = 365) '→' date (2012, 12, 31) ' –

26

Вы можете использовать Python-dateutil'srelativedelta прирастить 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 будет содержать "1 апреля 2013 года".

NB: К сожалению, datetime выводит только значения дня как «десятичные числа» - то есть с начальными нулями, если они являются однозначными числами. .replace() в конце является обходным решением для решения этой проблемы, скопированной с @Alex Martelli (см. this question за его и другие подходы к этой проблеме).

8

По вашему вопросу, вы хотели бы просто увеличить год своей даты, а не беспокоиться о последствиях года. Вы можете использовать класс даты, чтобы сделать это, обратившись к году его членства.

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) 

Если у вас возникли проблемы с созданием определенного формата, сообщите нам об этом.

+0

Не беспокоясь о високосных годах приводит к плохой код. –

+0

@ AntonyHatchkins: можете ли вы объяснить, почему код в этом ответе плох? Мне кажется. –

+16

'z = datetime (2012,02,29); z.replace (z.year + 1) '->' ValueError: день за пределами допустимого диапазона за месяц –

72

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

Если вы хотите другой возможности (меняющийся 29 февраля по 28 февраля), то последняя строка должна быть изменена на:

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

Эта чертова функция должна быть в самом python ... – PedroMorgan

+2

Правильно, надеюсь, они добавят. – WebOrCode

+2

ответы разные: 'relativedelta()' хранит последний день месяца, т. Е. 'Date (2016, 2, 29) + relativedelta (years = 1) == date (2017, 2, 28)'. Ваше решение дает (как задокументировано) первый день следующего месяца: 'add_years (date (2016,2,29), 1) == date (2017, 3, 1)' – jfs

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) 
44445164 +10617451515053691368888

И выход из этого примера:

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

Это то, что я делаю, когда нужно добавить несколько месяцев или лет и не хотят импортировать больше библиотек. Просто создайте объект 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))) 
Смежные вопросы