Как я могу вычесть или добавить 100 лет к полю даты и времени в базе данных в Django?

Как я могу вычесть или добавить 100 лет к полю datetime в базе данных в Django?

Дата находится в базе данных, я просто хочу напрямую обновить поле, не извлекая его, чтобы вычислить, а затем вставить.


person kelvinfix    schedule 03.05.2011    source источник
comment
Что ты имеешь в виду? Вы хотите изменить все даты в базе данных на 100 лет? Вы хотите написать запрос, который сравнивает дату + 100 лет? Вы просто хотите вывести даты с добавлением 100 лет? Какой?   -  person Daniel Roseman    schedule 03.05.2011
comment
Напишите что-то вроде queryset.update(end_time=end_time + 1)   -  person kelvinfix    schedule 03.05.2011


Ответы (6)


Я бы использовал функцию relativedelta пакета dateutil.relativedelta, которая даст вам более точный расчет «n лет назад»:

from dateutil.relativedelta import relativedelta
import datetime

years_ago = datetime.datetime.now() - relativedelta(years=5)

Затем просто обновите поле date, как показано здесь другими.

person Max    schedule 03.05.2011
comment
Я даже никогда не слышал об этом пакете (но он установлен в моей системе). Я не помню, чтобы устанавливал его, так что есть идеи, включен ли он каким-то образом в другой пакет? - person Gerrat; 06.09.2011
comment
Это часть python-dateutil - person Max; 06.09.2011
comment
Это пакет, который я не помню, устанавливал. Однако нашел свой ответ - он установлен вместе с Matplotlib, если он еще не установлен. - person Gerrat; 06.09.2011
comment
Я сделал серьезное тестирование на этом сегодня. timedelta(days=365*100) неверна. timedelta(days=365,25*100) имеет несколько выбросов, которые не работают. timedelta(days=365.24*100) ближе, но я нашел пару исключений. относительная дельта (годы = 100) работает каждый раз. Теперь дурацкое хранилище формата даты «%m%d%y», с которым мне приходится иметь дело, будет всегда правильным (ну... по крайней мере, если они говорят о датах больше 1917 года. Трудно отличить 2016 год от 1916 года с никакого другого контекста.Но 2018 еще не наступил) Так что ура! - person Alan Leuthard; 04.08.2017
comment
См. stackoverflow.com/questions/12433233/ для получения более подробной информации о относительной дельте - person mic; 26.08.2019

Используйте timedelta. Что-то вроде этого должно помочь:

import datetime
years = 100
days_per_year = 365.24
hundred_years_later = my_object.date + datetime.timedelta(days=(years*days_per_year))
person Vladimir Prudnikov    schedule 03.05.2011

Метод .update() в наборе запросов Django позволяет обновлять все значения, не извлекая объект из базы данных. Вы можете обратиться к существующему значению, используя F() объект.

К сожалению, временная дельта Python не работает с годами, поэтому вам придется вычислить 100 лет, выраженных в днях (это 36524,25):

MyModel.objects.update(timestamp=F('timestamp')+timedelta(days=36524.25))
person Will Hardy    schedule 03.05.2011
comment
Просто для справки: использование объектов F() с такими временными дельтами доступно только в Django 1.3 или более поздних версиях. - person John Montgomery; 03.05.2011
comment
Это игнорирует високосные дни, такие как 2012-02-29, лучше используйте relativedate() вместо timedelta(), если вам нужна такая точность. - person vdboor; 29.02.2012
comment
Я был бы очень удивлен, если бы это работало с F() объектами. .2425 в числе 365.2425 — это бит, который пытается учитывать високосные годы, насколько это возможно с F() объектами. - person Will Hardy; 01.03.2012

Хотя установка количества дней в году как 365.25 (от (365+365+365+366)/4) полностью компенсирует ошибку разницы в днях, иногда это приводит к нежелательным результатам, поскольку вы можете вызвать нежелательные изменения в атрибутах, отличных от year. , особенно когда вы добавляете/вычитаете 1 или несколько лет.

Если вы хотите просто изменить year, не допуская изменений в других атрибутах даты и времени, просто выполните алгебру для атрибута year следующим образом:

from datetime import datetime 

d = my_obj.my_datetime_field

""" subtract 100 years. """
my_obj.my_datetime_field = datetime(d.year-100, d.month, d.day, d.hour, d.minute, d.second, d.microsecond, d.tzinfo)

my_obj.save()

Надеюсь, поможет!

person xemexpress    schedule 19.04.2020
comment
Хотя этот код может решить проблему, включая объяснение того, как и почему это решает проблему, действительно поможет улучшить качество. вашего сообщения и, вероятно, приведет к большему количеству голосов. Помните, что вы отвечаете на вопрос для будущих читателей, а не только для того, кто задает сейчас. Пожалуйста, отредактируйте свой ответ, чтобы добавить пояснения и указать, какие ограничения и предположения применяются. - person Brian; 19.04.2020

Я знаю, что это старый вопрос, но у меня была проблема найти хороший способ решить мою проблему, я создал это: используйте плюс (+) или минус (-) для обработки:

import datetime # Don't forget to import it

def subadd_date(date,years):
    ''' Subtract or add Years to a specific date by pre add  + or - '''
    if isinstance(date,datetime.datetime) and isinstance(years,int):
        day,month,year = date.day , date.month , date.year
        #If you want to have HOUR, MINUTE, SECOND 
        #With TIME: 
        # day,month,year,hour,minute,second = date.day, date.month,date.year,date.hour,date.minute,date.second  

        py = year + years # The Past / Futur Year
        new_date_str = "%s-%s-%s" % (day,month,py) # New Complete Date
        # With TIME : new_date_str = "%s-%s-%s %s:%s:%s" % (month,day,py,hour,minute,second)
        try:
            new_date = datetime.datetime.strptime(new_date_str,"%d-%m-%Y")
        except ValueError: # day is out of range for month (February 29th)
            new_date_str = "%s-%s-%s" % (1,month+1,py) # New Complete Date : March 1st
            new_date = datetime.datetime.strptime(new_date_str,"%d-%m-%Y")

        return new_date
        # With TIME : return datetime.datetime.strptime(new_date_str,"%d-%m-%Y %H:%M:%Y")
    return None
person Lemayzeur    schedule 13.12.2017

Вычтите год из сегодняшнего дня и используйте этот формат. х = дата-время.дата-время (2020 - 100, 5, 17)

import datetime
datetime.date(datetime.date.today().year - 100, datetime.date.today().month, datetime.date.today().day)
person Pravin L    schedule 17.04.2021