วิธีการเพิ่มวันที่และเวลาโดยหนึ่งวัน?


152

วิธีเพิ่มวันของวันที่หรือเวลา

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

แต่ฉันต้องการผ่านเดือนและปีอย่างถูกต้อง? ความคิดใด ๆ

คำตอบ:




12

นี่เป็นอีกวิธีในการเพิ่มวันในวันที่โดยใช้ relativedelta ของ relutived

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

เอาท์พุท:

วันนี้: 25/06/2015 20:41:44 น

After a Days: 01/06/2015 20:41:44 น


1
ทำไมคุณจะใช้มันแทนtimedelta()stdlib
jfs

2
@JFSebastian เพียงเพื่อแบ่งปันวิธีที่เป็นไปได้ในการเพิ่มวัน
Atul Arvind

1
หากไม่มีข้อได้เปรียบฉันไม่คิดว่ามันจะเพิ่มคุณค่า
Tejas Manohar

10

คำตอบปัจจุบันทั้งหมดไม่ถูกต้องในบางกรณีเนื่องจากพวกเขาไม่คิดว่าเขตเวลาจะเปลี่ยนค่าออฟเซ็ตที่สัมพันธ์กับ UTC ดังนั้นในบางกรณีการเพิ่ม 24 ชั่วโมงจึงแตกต่างจากการเพิ่มวันในปฏิทิน

ทางออกที่เสนอ

วิธีแก้ปัญหาต่อไปนี้ใช้งานได้กับซามัวและรักษาเวลาท้องถิ่นให้คงที่

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

รหัสทดสอบ

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

ผลการทดสอบ

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

คำตอบอื่น ๆ นั้นไม่ได้ผิดทั้งหมดพวกเขาทำงานได้อย่างสมบูรณ์แบบในขณะที่ทำงานกับ UTC หรือชุดข้อมูลไร้เดียงสา ( tzinfo == None)
Delgan

3

นี่เป็นทางออกที่ตรงไปตรงมาสำหรับฉัน:

from datetime import timedelta, datetime

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

0

คุณสามารถนำเข้า timedelta เพื่อให้รหัสสะอาดขึ้น

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

จากนั้นแปลงเป็นสตริงวันที่

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

Python หนึ่งซับคือ

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

-2

ทางออกสั้น ๆ ที่ไม่มีไลบรารีเลย :)

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

ตรวจสอบให้แน่ใจว่า " string d " เป็นจริงในรูปแบบ%m/%d/%Yเพื่อให้คุณไม่มีปัญหาในการเปลี่ยนจากหนึ่งเดือนเป็นเดือนถัดไป


2
ถ้าคุณตั้งdไปแล้วผลตอบแทนนี้8/31/18 8/32/18หากคุณเปลี่ยนปีจาก18มันก็แค่พัก
andrewsi
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.