On 9/18/2012 7:04 PM, Christopher Nelson wrote: >>> If I want to do: >>> >>> d = datetime.now() >>> cursor.execute("INSERT INTO mytable VALUES", somefunc(d)) >>> >>> what is `somefunc()` >>> >> >> Well, I think you're looking for to_utimestamp: >> >> http://www.edgewall.org/docs/branches-1.0-stable/html/api/trac_util_datefmt.html#trac.util.datefmt.to_utimestamp > > I'm seeing: > > File > "/usr/local/lib/python2.6/dist-packages/Trac-0.11.6-py2.6.egg/trac/util/datefmt.py", > line 69, in to_utimestamp > diff = dt - _epoc > TypeError: can't subtract offset-naive and offset-aware datetimes > > No doubt I'm passing a bad argument but the document you pointed to > doesn't indicate if the argument should be offset-naive or > offset-aware. >
You're right, this is not yet documented. As an aside, when playing on the command line with the datefmt utilities, I found some surprising differences between our FixedOffset tzinfo class and the tzinfo classes from pytz: I expected the "Europe/Paris" timezone from pytz to be the same as our "GMT +2:00" (when DST is active that is, otherwise GMT +1), but they are not... >>> from trac.util.datefmt import * >>> paris = timezone("Europe/Paris") >>> gmt02 = timezone("GMT +2:00") >>> (paris, gmt02) (<DstTzInfo 'Europe/Paris' PMT+0:09:00 STD>, <FixedOffset "GMT +2:00" 2:00:00>) I have no idea why that DstTzInfo instance shows "PMT+0:09:00", but OK. First we start by using "naive" datetime objects. >>> from datetime import datetime >>> d_naive = datetime.now() >>> d_paris = to_datetime(d_naive, paris) >>> d_gmt02 = to_datetime(d_naive, gmt02) Now if we try to use to_utimestamp() on these datetime objects, we'll get different values! >>> to_utimestamp(d_paris) 1347999789289000L >>> to_utimestamp(d_gmt02) 1347993129289000L ?? But even when comparing directly those datetime objects, we see they're not the same: >>> d_paris - d_gmt02 datetime.timedelta(0, 6660) !? 111 minutes... At first I had no idea what this corresponded to. The Python docs (http://docs.python.org/library/datetime.html#datetime-objects) helped a bit here: "Subtraction of a datetime from a datetime ... If both are aware and have different tzinfo attributes, a-b acts as if a and b were first converted to naive UTC datetimes first. The result is ..." (in our example:) >>> (d_paris.replace(tzinfo=None) - d_paris.utcoffset()) - (d_gmt02.replace(tzinfo=None) - d_gmt02.utcoffset()) datetime.timedelta(0, 6660) And this helps to pinpoint the cause: >>> d_gmt02.utcoffset() datetime.timedelta(0, 7200) (correct, 2 hours) >>> d_paris.utcoffset() datetime.timedelta(0, 540) Ahem, 9 minutes... (remember the PMT+0:09:00 above?) Googling a bit reveals a similar "surprise" for someone else, a few years ago: http://marc.info/?l=zope3-dev&m=115384670611141&w=2 The answer was: "Read pytz/README.txt. You're not supposed to pass tzinfo to datetime." Ok, so it really look like we should find an alternative to the t.replace(tzinfo=tzinfo) we do in to_datetime() when t is a "naive" datetime, because if we specify there a timezone from pytz, we'll get non-sensical datetime objects. If we start with "aware" datetime objects (bootstrapping the tzinfo with one of our own FixedOffset instance), it indeed works as expected. >>> d_utc = d_naive.replace(tzinfo=utc) >>> du_paris = to_datetime(d_utc, paris) >>> du_gmt02 = to_datetime(d_utc, gmt02) Then: >>> du_paris - du_gmt02 datetime.timedelta(0) Better! Looks like in Trac we're mostly using "aware" datetime objects anyway, like when retrieving dates from the database (from_utimestamp(usecs)) or from the user (user_time(...)), or the current date (datetime.now(utc)), so that this problem was not apparent. Still, the docs need to be clarified about the "naive"/"aware" situation and to_datetime() should be fixed. -- Christian -- You received this message because you are subscribed to the Google Groups "Trac Development" group. To post to this group, send email to trac-dev@googlegroups.com. To unsubscribe from this group, send email to trac-dev+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/trac-dev?hl=en.