Hi, Easiest way is to change the time to seconds, add as many seconds as a year/month/week/day/hour/minutes represent and then transform it back.
E.g. >>> time.time() 1324031491.026137 >>> time.time() + 3600 # Add an hour 1324035105.082003 >>> time.gmtime(time.time() + 3600) time.struct_time(tm_year=2011, tm_mon=12, tm_mday=16, tm_hour=11, tm_min=31, tm_sec=57, tm_wday=4, tm_yday=350, tm_isdst=0) >>> On 16 December 2011 10:45, Ulrich Eckhardt <ulrich.eckha...@dominolaser.com> wrote: > Hi! > > I'm trying to create a struct_time that is e.g. one year ahead or a month > back in order to test some parsing/formatting code with different dates. > > Now, the straightforward approach is > > t = time.localtime() > t.tm_year += 1 > > This fails with "TypeError: readonly attribute". This kind-of makes sense, > as an immutable object allows you to use it as key in a dict. > > > The second approach is this: > > l = list(t) # convert to a sequence > l[0] += 1 # increment year > t = time.struct_time(l) # convert to a struct_time > > This works but is ugly, because the code relies on the order inside the list > and uses magic numbers to access them. The order is AFAICT not accessible > programmatically but only documented, and not even in a way that makes clear > that it is part of the API and as such actualy guaranteed. I could try to > assert that the indices match using "if l[0] is t.tm_year", but this is > still ugly. > > > The next approach I tried was to simply create a derived class: > > class my_time(time.struct_time): > pass > > This fails again with "TypeError: Error when calling the metaclass bases, > type 'time.struct_time' is not an acceptable base type. I could try to > encapsulate a struct_time and delegate attribute access to it in order to do > this, but it also seems overkill. Also, using an immutable type as a > baseclass and delegating access to members seems like hackery to me, prone > to fail in situations where it is least expected. > > > Then I tried duck typing. If it quacks like a duck, it better not be a > crocodile! This looks like this: > > struct my_time(object): pass > t = my_time() > t.tm_year = 2012 > t.tm_month = 12 > t.tm... # other fields accordingly > time.mktime(t) > > This fails with "TypeError: argument must be 9-item sequence, not my_time". > I thought about using a collections.namedtuple, because a namedtuple is a > tuple and therefore also a sequence, but that only leads me back to the > problem that time.mktime() takes a sequence and the order of the sequence is > not accessible programmatically. > > > A last approach was to convert the thing to a dict and back. Alas, there is > no conversion to a dict, otherwise > > d = dict(t) > d['tm_year'] += 1 > t = time.struct_time(d) > > would have been a straightforward approach. > > > Does anyone have a suggestion how to solve this elegantly and pythonically? > Also, what I'm wondering is if the lack of a clear way should be considered > a bug or not. > > > Cheers! > > Uli > > -- > http://mail.python.org/mailman/listinfo/python-list -- http://mail.python.org/mailman/listinfo/python-list