Python: get datetime for'3 years ago today'

W Pythonie, jak uzyskać obiekt datetime dla '3 years ago today'?

UPDATE: FWIW, nie obchodzi mnie dokładność... tzn. dzisiaj jest 29 lutego, nie obchodzi mnie czy w mojej odpowiedzi podam 28 lutego czy 1 marca. W tym przypadku zwięzłość jest ważniejsza niż konfigurowalność.

Author: Acumenus, 2011-03-01

8 answers

import datetime
datetime.datetime.now() - datetime.timedelta(days=3*365)
 96
Author: Fábio Diniz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-03-01 17:45:30

Jeśli chcesz być dokładny użyj modułu dateutil do obliczania dat względnych

from datetime import datetime
from dateutil.relativedelta import relativedelta

three_yrs_ago = datetime.now() - relativedelta(years=3)
 141
Author: Vince Spicer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-10-05 20:25:09

Odjęcie 365*3 dni jest oczywiście złe--przekraczasz rok przestępny ponad połowę czasu.

dt = datetime.now()
dt = dt.replace(year=dt.year-3)
# datetime.datetime(2008, 3, 1, 13, 2, 36, 274276)

ED: aby uzyskać prawo do wydania roku przestępnego,

def subtract_years(dt, years):
    try:
        dt = dt.replace(year=dt.year-years)
    except ValueError:
        dt = dt.replace(year=dt.year-years, day=dt.day-1)
    return dt
 27
Author: Glenn Maynard,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-03-01 18:14:46
def add_years(dt, years):
    try:
        result = datetime.datetime(dt.year + years, dt.month, dt.day, dt.hour, dt.minute, dt.second, dt.microsecond, dt.tzinfo)
    except ValueError:
        result = datetime.datetime(dt.year + years, dt.month, dt.day - 1, dt.hour, dt.minute, dt.second, dt.microsecond, dt.tzinfo)
    return result

>>> add_years(datetime.datetime.now(), -3)
datetime.datetime(2008, 3, 1, 12, 2, 35, 22000)
>>> add_years(datetime.datetime(2008, 2, 29), -3)
datetime.datetime(2005, 2, 28, 0, 0)
 4
Author: Mark Ransom,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-03-01 18:04:10

Chociaż odpowiedź za pomocą dateutil jest dobry, alternatywą jest użycie pendulum Paczka na PyPI. Aby uzyskać więcej informacji, zapoznaj się z jej docs.

>>> import pendulum
>>> dt = pendulum.now().subtract(years=3)
>>> dt
DateTime(2015, 10, 5, 17, 44, 41, 82598, tzinfo=Timezone('America/New_York'))
>>> type(dt)
pendulum.datetime.DateTime

Jeśli potrzebujesz bieżącej datetime do dalszego użycia, prawdopodobnie powinieneś najpierw zapisać pendulum.now() do zmiennej, a następnie użyć zmiennej!

Jeśli naprawdę chcesz uniknąć strefy czasowej, użyj .naive().

Nie powinieneś konwertować wyniku do natywnego obiektu Pythona, ale jeśli naprawdę trzeba, jednym ze sposobów jest:

>>> import datetime
>>> pydt = datetime.datetime.fromisoformat(dt.isoformat())
>>> pydt
datetime.datetime(2015, 10, 5, 17, 44, 41, 82598, tzinfo=datetime.timezone(datetime.timedelta(days=-1, seconds=72000)))
>>> type(pydt)
datetime.datetime
 2
Author: Acumenus,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-10-05 22:46:44

Nie widzisz tego i to jest bardzo proste i zwięzłe,

In [1]: import datetime

In [2]: dt = datetime.datetime.today()

In [3]: datetime.datetime(year=dt.year-3, month=dt.month, day=dt.day)
Out[3]: datetime.datetime(2016, 4, 11, 0, 0)

Zastrzeżenie jest to, że spowoduje to błąd 29 lutego.

 1
Author: Josh Herzberg,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-04-11 16:12:54
In [3]: import datetime as dt

In [4]: today=dt.date.today()

In [5]: three_years_ago=today-dt.timedelta(days=3*365)

In [6]: three_years_ago
Out[6]: datetime.date(2008, 3, 1)
 -1
Author: unutbu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-03-01 17:44:38

Dlaczego po prostu nie sprawdzić roku przestępnego przed zastąpieniem roku. To nie wymaga żadnego dodatkowego pakietu lub spróbuj: Except.

def years_ago(dt, years):
    if dt.month == 2 and dt.day == 29:
        dt = dt.replace(day=28)

    return dt.replace(year=dt.year - years)
 -1
Author: milkbread,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-12-24 09:22:44