Bagaimana cara menambah datetime satu hari?


152

Bagaimana cara meningkatkan hari datetime?

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

Tetapi saya perlu melewati bulan dan tahun dengan benar? Ada ide?

Jawaban:




12

Berikut adalah metode lain untuk menambahkan hari pada tanggal menggunakan relativedelta 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')

Keluaran:

Hari ini: 25/06/2015 20:41:44

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


1
mengapa Anda menggunakannya bukan timedelta()dari stdlib?
jfs

2
@ JFSebastian Hanya untuk membagikan kemungkinan cara lain untuk menambah hari.
Atul Arvind

1
Jika tidak ada keuntungan, saya tidak berpikir itu menambah nilai.
Tejas Manohar

10

Semua jawaban saat ini salah dalam beberapa kasus karena mereka tidak menganggap bahwa zona waktu mengubah offsetnya relatif terhadap UTC. Jadi, dalam beberapa kasus, menambah 24 jam berbeda dengan menambahkan hari kalender.

Solusi yang diajukan

Solusi berikut berfungsi untuk Samoa dan menjaga waktu lokal tetap konstan.

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

Kode yang Diuji

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

Hasil tes

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

Jawaban yang lain tidak sepenuhnya salah, mereka baik-baik saja saat bekerja dengan UTC atau data naif ( tzinfo == None).
Delgan

3

Ini solusi mudah bagi saya:

from datetime import timedelta, datetime

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

0

Anda juga dapat mengimpor timedelta sehingga kodenya lebih bersih.

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

Kemudian konversikan ke tanggal menjadi string

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

Python one liner adalah

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

-2

Solusi singkat tanpa perpustakaan sama sekali. :)

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

Pastikan " string d " benar-benar dalam bentuk %m/%d/%Ysehingga Anda tidak akan mengalami masalah transisi dari satu bulan ke bulan berikutnya.


2
jika Anda mengatur duntuk 8/31/18kemudian kembali ini 8/32/18. Jika Anda mengubah tahun dari 18, itu hanya rusak.
andrewsi
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.