Làm thế nào để tăng thời gian một ngày?


151

Làm thế nào để tăng ngày của một datetime?

for i in range(1, 35)
    date = datetime.datetime(2003, 8, i)
    print(date)

Nhưng tôi cần vượt qua tháng và năm một cách chính xác? Có ý kiến ​​gì không?

Câu trả lời:



60

Ngày tăng có thể được thực hiện bằng cách sử dụng các đối tượng timedelta:

import datetime

datetime.datetime.now() + datetime.timedelta(days=1)

Tra cứu các đối tượng timedelta trong tài liệu Python: http://docs.python.org/l Library / datetime.html


12

Đây là một phương pháp khác để thêm ngày vào ngày bằng cách sử dụng relativeelta của dateutil.

from datetime import datetime
from dateutil.relativedelta import relativedelta

print 'Today: ',datetime.now().strftime('%d/%m/%Y %H:%M:%S') 
date_after_month = datetime.now()+ relativedelta(day=1)
print 'After a Days:', date_after_month.strftime('%d/%m/%Y %H:%M:%S')

Đầu ra:

Hôm nay: 25/06/2015 20:41:44

Sau một ngày: 01/06/2015 20:41:44


1
Tại sao bạn sẽ sử dụng nó thay vì timedelta()từ stdlib?
jfs

2
@JFSebastian Chỉ cần chia sẻ một cách có thể khác để thêm ngày.
Atul Arvind

1
Nếu không có lợi thế, tôi không nghĩ nó tăng thêm giá trị.
Tejas Manohar

10

Tất cả các câu trả lời hiện tại đều sai trong một số trường hợp vì họ không cho rằng các múi giờ thay đổi phần bù của chúng so với UTC. Vì vậy, trong một số trường hợp, việc thêm 24h khác với việc thêm một ngày theo lịch.

Giải pháp đề xuất

Giải pháp sau đây hoạt động cho Samoa và giữ cho thời gian địa phương không đổi.

def add_day(today):
    """
    Add a day to the current day.

    This takes care of historic offset changes and DST.

    Parameters
    ----------
    today : timezone-aware datetime object

    Returns
    -------
    tomorrow : timezone-aware datetime object
    """
    today_utc = today.astimezone(datetime.timezone.utc)
    tz = today.tzinfo
    tomorrow_utc = today_utc + datetime.timedelta(days=1)
    tomorrow_utc_tz = tomorrow_utc.astimezone(tz)
    tomorrow_utc_tz = tomorrow_utc_tz.replace(hour=today.hour,
                                              minute=today.minute,
                                              second=today.second)
    return tomorrow_utc_tz

Mã kiểm tra

# core modules
import datetime

# 3rd party modules
import pytz


# add_day methods
def add_day(today):
    """
    Add a day to the current day.

    This takes care of historic offset changes and DST.

    Parameters
    ----------
    today : timezone-aware datetime object

    Returns
    -------
    tomorrow : timezone-aware datetime object
    """
    today_utc = today.astimezone(datetime.timezone.utc)
    tz = today.tzinfo
    tomorrow_utc = today_utc + datetime.timedelta(days=1)
    tomorrow_utc_tz = tomorrow_utc.astimezone(tz)
    tomorrow_utc_tz = tomorrow_utc_tz.replace(hour=today.hour,
                                              minute=today.minute,
                                              second=today.second)
    return tomorrow_utc_tz


def add_day_datetime_timedelta_conversion(today):
    # Correct for Samoa, but dst shift
    today_utc = today.astimezone(datetime.timezone.utc)
    tz = today.tzinfo
    tomorrow_utc = today_utc + datetime.timedelta(days=1)
    tomorrow_utc_tz = tomorrow_utc.astimezone(tz)
    return tomorrow_utc_tz


def add_day_dateutil_relativedelta(today):
    # WRONG!
    from dateutil.relativedelta import relativedelta
    return today + relativedelta(days=1)


def add_day_datetime_timedelta(today):
    # WRONG!
    return today + datetime.timedelta(days=1)


# Test cases
def test_samoa(add_day):
    """
    Test if add_day properly increases the calendar day for Samoa.

    Due to economic considerations, Samoa went from 2011-12-30 10:00-11:00
    to 2011-12-30 10:00+13:00. Hence the country skipped 2011-12-30 in its
    local time.

    See https://stackoverflow.com/q/52084423/562769

    A common wrong result here is 2011-12-30T23:59:00-10:00. This date never
    happened in Samoa.
    """
    tz = pytz.timezone('Pacific/Apia')
    today_utc = datetime.datetime(2011, 12, 30, 9, 59,
                                  tzinfo=datetime.timezone.utc)
    today_tz = today_utc.astimezone(tz)  # 2011-12-29T23:59:00-10:00
    tomorrow = add_day(today_tz)
    return tomorrow.isoformat() == '2011-12-31T23:59:00+14:00'


def test_dst(add_day):
    """Test if add_day properly increases the calendar day if DST happens."""
    tz = pytz.timezone('Europe/Berlin')
    today_utc = datetime.datetime(2018, 3, 25, 0, 59,
                                  tzinfo=datetime.timezone.utc)
    today_tz = today_utc.astimezone(tz)  # 2018-03-25T01:59:00+01:00
    tomorrow = add_day(today_tz)
    return tomorrow.isoformat() == '2018-03-26T01:59:00+02:00'


to_test = [(add_day_dateutil_relativedelta, 'relativedelta'),
           (add_day_datetime_timedelta, 'timedelta'),
           (add_day_datetime_timedelta_conversion, 'timedelta+conversion'),
           (add_day, 'timedelta+conversion+dst')]
print('{:<25}: {:>5} {:>5}'.format('Method', 'Samoa', 'DST'))
for method, name in to_test:
    print('{:<25}: {:>5} {:>5}'
          .format(name,
                  test_samoa(method),
                  test_dst(method)))

Kết quả kiểm tra

Method                   : Samoa   DST
relativedelta            :     0     0
timedelta                :     0     0
timedelta+conversion     :     1     0
timedelta+conversion+dst :     1     1

Các câu trả lời khác không hoàn toàn sai, chúng hoàn toàn tốt trong khi làm việc với UTC hoặc tzinfo == Nonedatetimes ngây thơ ( ).
Delgan

3

Đây là một giải pháp đơn giản cho tôi:

from datetime import timedelta, datetime

today = datetime.today().strftime("%Y-%m-%d")
tomorrow = datetime.today() + timedelta(1)

0

Bạn cũng có thể nhập timedelta để mã sạch hơn.

from datetime import datetime, timedelta
date = datetime.now() + timedelta(seconds=[delta_value])

Sau đó chuyển đổi thành ngày thành chuỗi

date = date.strftime('%Y-%m-%d %H:%M:%S')

Python một lớp lót là

date = (datetime.now() + timedelta(seconds=[delta_value])).strftime('%Y-%m-%d %H:%M:%S')

-2

Một giải pháp ngắn mà không có thư viện nào cả. :)

d = "8/16/18"
day_value = d[(d.find('/')+1):d.find('/18')]
tomorrow = f"{d[0:d.find('/')]}/{int(day_value)+1}{d[d.find('/18'):len(d)]}".format()
print(tomorrow)
# 8/17/18

Đảm bảo rằng " chuỗi d " thực sự ở dạng %m/%d/%Yđể bạn sẽ không gặp vấn đề khi chuyển từ tháng này sang tháng khác.


2
nếu bạn đặt dthành 8/31/18thì điều này trở lại 8/32/18. Nếu bạn thay đổi năm từ 18, nó chỉ phá vỡ.
andrewsi
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.