modifying a time.struct_time
Mazen Harake
mazen.harake at gmail.com
Fri Dec 16 05:32:13 EST 2011
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.eckhardt at 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
More information about the Python-list
mailing list