Python: получите дату и время для «3 года назад сегодня» - PullRequest
42 голосов
/ 01 марта 2011

В Python, как мне получить объект datetime для «3 года назад сегодня»?

ОБНОВЛЕНИЕ: FWIW, меня не волнует точность ... то есть сегодня 29 февраляМне все равно, будет ли мне дан ответ 28 февраля или 1 марта.В данном случае краткость важнее, чем конфигурируемость.

Ответы [ 8 ]

110 голосов
/ 01 марта 2011

Если вам нужно быть точным, используйте модуль dateutil для расчета относительных дат

from datetime import datetime
from dateutil.relativedelta import relativedelta

three_yrs_ago = datetime.now() - relativedelta(years=3)
57 голосов
/ 01 марта 2011
import datetime
datetime.datetime.now() - datetime.timedelta(days=3*365)
19 голосов
/ 01 марта 2011

Вычитать 365 * 3 дня, конечно, неправильно - вы пересекаете високосный год более, чем вдвое.

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

ED: Чтобы решить проблему високосного года,

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
4 голосов
/ 01 марта 2011
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)
1 голос
/ 06 октября 2018

Хотя ответ с использованием dateutil является хорошим, альтернативой является использование пакета pendulum в PyPI.Для получения дополнительной информации обратитесь к документам .

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

Если вам понадобится текущая дата и время для дальнейшего использования, вам, вероятно, следует сначала сохранить pendulum.now() в переменной, изатем используйте переменную!

Если вы действительно хотите избежать часового пояса, используйте .naive().

Вам не нужно преобразовывать результат в собственный объект Python, но если вы действительнонужно, один из способов сделать это:

>>> 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
0 голосов
/ 11 апреля 2019

Не вижу этого, и это очень просто и лаконично,

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)

Предостережение в том, что это вызовет ошибку 29 февраля.

0 голосов
/ 31 мая 2016

Почему бы просто не сделать проверку на високосный год перед заменой года. Для этого не нужно никаких дополнительных пакетов или попробуйте: кроме.

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)
0 голосов
/ 01 марта 2011
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)
...