2013-04-01 33 views
36

Tôi đã lấy một ngày từ cơ sở dữ liệu như sau biếnThêm một năm trong PYTHON ngày hiện tại

{{ i.operation_date }} 

mà tôi nhận được một giá trị như

April 1, 2013 

tôi cần để thêm một năm vào phần trên, để tôi có thể nhận được

April 1, 2014 

Vui lòng đề xuất, làm cách nào tôi có thể thực hiện việc này?

+4

[Bạn đã thử gì?] (Http://mattgemmell.com/2008/12/08/what-have-you-tried/) –

+0

Nếu bạn muốn làm điều này trong các mẫu chỉ, sau đó xem http://stackoverflow.com/questions/10715253/display-timestamp-in-django-template này. Bây giờ bạn có thể viết một thẻ mẫu có thể thêm một năm vào giá trị hiện tại. –

+0

liên quan: [Cách chuyển đổi từ giây sang giây] (http://stackoverflow.com/a/32658742/4279) – jfs

Trả lời

-1

chuyển đổi nó thành đối tượng ngày giờ trăn nếu nó chưa được. sau đó thêm deltatime

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

cho trường hợp ngày của bạn = 365.

bạn có thể có điều kiện để kiểm tra xem năm là bước nhảy vọt hay không và điều chỉnh ngày phù hợp

bạn có thể thêm bao nhiêu năm như bạn muốn

+4

−1 vì năm nhuận: 'ngày (2012, 1, 1) + timedelta (ngày = 365) '→' date (2012, 12, 31) ' –

26

Bạn có thể sử dụng Python-dateutil'srelativedelta để tăng một đối tượng datetime trong khi vẫn nhạy cảm với những thứ như năm nhuận và độ dài tháng. Python-dateutil được đóng gói với matplotlib nếu bạn đã có. Bạn có thể làm như sau:

from dateutil.relativedelta import relativedelta 

new_date = old_date + relativedelta(years=1) 

(Câu trả lời này được đưa ra bởi @Max đến similar question).

Nhưng nếu ngày của bạn là một chuỗi (ví dụ: chưa một đối tượng datetime), bạn có thể chuyển đổi nó bằng cách sử 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 sẽ chứa "1 tháng 4 năm 2013".

NB: Thật không may, datetime chỉ xuất ra giá trị ngày là "số thập phân" - nghĩa là với số 0 đứng đầu nếu chúng là số có một chữ số. Các .replace() ở cuối là một workaround để đối phó với vấn đề này sao chép từ @ Marta Martelli (xem this question cho các phương pháp tiếp cận của mình và khác cho vấn đề này).

8

Có vẻ như từ câu hỏi của bạn mà bạn muốn chỉ đơn giản là tăng năm của ngày đã cho thay vì lo lắng về các tác động năm nhuận. Bạn có thể sử dụng lớp ngày để làm điều này bằng cách truy cập năm thành viên của nó.

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) 

Nếu bạn gặp sự cố khi tạo định dạng cho sẵn, hãy cho chúng tôi biết.

+0

Không phải lo lắng về những năm nhuận sẽ dẫn đến mã nghèo nàn. –

+0

@AntonyHatchkins: bạn có thể giải thích tại sao mã trong câu trả lời này kém không? Nó có vẻ đúng với tôi. –

+16

'z = datetime (2012,02,29); z.replace (z.year + 1) '->' ValueError: ngày nằm ngoài phạm vi cho tháng ' –

72

AGSM's answer cho thấy cách thuận tiện để giải quyết vấn đề này bằng cách sử dụng gói python-dateutil. Nhưng nếu bạn không muốn cài đặt gói đó thì sao?Bạn có thể giải quyết vấn đề trong vanilla Python như thế này:

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

Nếu bạn muốn khả năng khác (thay đổi 29 Tháng Hai - 28 Tháng Hai) thì dòng cuối cùng nên được thay đổi:

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

Chức năng goddam này phải ở trong python ... – PedroMorgan

+2

Đúng, tôi hy vọng họ sẽ thêm vào. – WebOrCode

+2

câu trả lời là khác nhau: 'relativedelta()' giữ ngày cuối cùng của tháng, tức là 'ngày (năm 2016, 2, 29) + relativedelta (năm = 1) == ngày (2017, 2, 28)'. Giải pháp của bạn mang lại (như được ghi chép) vào ngày đầu tiên của tháng tiếp theo: 'add_years (ngày (2016,2,29), 1) == date (2017, 3, 1)' – jfs

0

Nhìn vào này: sử dụng

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

Ví dụ:

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) 

Và đầu ra của ví dụ này:

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

Đây là những gì tôi làm khi tôi cần thêm tháng hoặc nhiều năm và không muốn nhập nhiều thư viện. Chỉ cần tạo một đối tượng datetime.date(), gọi add_month (date) để thêm một tháng và add_year (date) để thêm một năm.

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))) 
Các vấn đề liên quan