Как * изменить * объект struct_time?
Когда вы работаете со временем и датами в python, вы наткнетесь на объект time.struct_time:
st = time.strptime("23.10.2012", "%d.%m.%Y")
print st
time.struct_time(tm_year=2012, tm_mon=10, tm_mday=23, tm_hour=0, tm_min=0,
tm_sec=0, tm_wday=1, tm_yday=297, tm_isdst=-1)
Теперь, когда эта структура не поддерживает назначение элемента (т.е. вы не можете сделать что-то вроде st[1]+=1
), как еще можно увеличить, скажем, номер месяца.
Решения предлагают преобразовать этот time_struct в секунды и добавить соответствующее количество секунд, но это выглядит не очень хорошо. Вы также должны знать, сколько дней в месяц, или год является високосным годом или нет. Я хочу простой способ получить time_struct, например,
time.struct_time(tm_year=2012, tm_mon=11, tm_mday=23, tm_hour=0, tm_min=0,
tm_sec=0, tm_wday=1, tm_yday=297, tm_isdst=-1)
только месяц увеличился на единицу. Создание time_struct
с нуля было бы неплохо, но как? Какие существуют способы?
Ответы
Ответ 1
Вместо этого используйте datetime
модуль, который имеет гораздо более богатый набор объектов для обработки арифметики даты (времени):
import datetime
adate = datetime.datetime.strptime("23.10.2012", "%d.%m.%Y").date()
adate + datetime.timedelta(days=30)
Вы можете использовать отличный python-dateutil
дополнительный модуль, чтобы получить более богатый набор возможностей для работы с дельтами:
from dateutil.relativedelta import relativedelta
adate + relativedelta(months=1)
relativedelta
знает о високосных годах, длинах месяцев и т.д. и будет делать правильные вещи при добавлении месяца, например, 30 января (вы закончите с 28 или 29 февраля, он не будет пересекать границы месяца),
Ответ 2
Итак... схема для кортежа, лежащего в основе time_struct, приведена здесь в документации:
http://docs.python.org/2/library/time.html#time.struct_time
И даже при том, что он доступен только для чтения как time_struct, вы можете использовать casting to list() для непосредственного доступа к этому кортежу (помните, чтобы обернуть ваш месяц после его увеличения и сохранить конечный диапазон в 1-12 а не 0-11). Затем функция time.struct_time()
преобразует верный 9-кортеж обратно в time_struct:
st = time.strptime("23.10.2012", "%d.%m.%Y")
st_writable = list(st)
st_writable[1] = (st_writable[1] + 1)%12 + 1
st = time.struct_time(tuple(st_writable))
Ответ 3
Вы можете сначала преобразовать его в datetime, а затем добавить к нему timedelta offset:
from time import mktime
from datetime import datetime
dt = datetime.fromtimestamp(mktime(struct))
timedelta = datetime.timedelta(seconds=10)
dt = dt + timedelta
Литература:
Ответ 4
Если вы хотите избежать совпадения времени и времени со временем, вы можете конвертировать в временную метку unix, а затем вычесть количество секунд, которое вам нужно. Чтобы получить объект времени 24 часа назад:
time.gmtime(time.mktime(time.gmtime()) - 86400)
Однако, поскольку OP указал, что это плохо для работы с месяцами и должно быть зарезервировано на секунды, часы и дни.