[Zope3-dev] mini-RFC: times and timezones

Gary Poster gary at zope.com
Sat Feb 26 18:23:50 EST 2005


On Feb 25, 2005, at 8:18 PM, Marius Gedminas wrote:

> On Wed, Feb 23, 2005 at 10:26:42PM -0500, Gary Poster wrote:
> <snip list of suggestions>
>>   * Views should generally display dates (stored with a UTC timezone)
>> using something like this:
>>         formatter = request.locale.dates.getFormatter('dateTime',
>> length='short')
>>         tz = zope.interface.common.tzinfo.ITZInfo(request)
>>         return formatter.format(zope.i18n.switchTimeZones(date, tz)
>
> This looks like a mouthful.  Can we invent an obvious way to display
> dates and times without having to remember weird three-line
> incantations?  (Can anyone remember how to open a text file in Java
> without looking it up?)

A good point.  Before talking about it more, for what it's worth, 
here's the current revision of the three lines:

from zope.interface.common.tzinfo import ITZInfo
formatter = request.locale.dates.getFormatter('dateTime', 
length='short')
return formatter.format(date.astimezone(ITZInfo(request)))

The only change from the current recommended pattern (using the locale 
formatter) is the "astimezone" call with the ITZInfo adaptation.

The ITZInfo adaptation doesn't seem too onerous to me within the 
context of using the locale formatter.  Marius, if you would like the 
whole thing shorter (very reasonable), maybe we could register an 
adapter for (datetime, request) (IView is deprecated so not sure what 
we'd provide...) that did the right thing.  Maybe named views for the 
four formatter length values would work.  It should in theory.  
Derrick's suggestion of a zapi call is fine too, although I think I'd 
prefer an adaptation.  I think these conveniences can be worked out 
gradually.

>> Objections?  I'd like schoolbell(/tool) folks to buy in on this as
>> well, ideally.  This should be pretty easy for me to throw together if
>> everyone is ok with it.
>
> I have no objections (although I haven't thought very deeply about the
> issue).  Storing dates in UTC and converting to some other timezone on
> display is the way to go.  I am not sure sure whether to use UTC
> datetimes without timezone info (what datetime.utcnow returns), or 
> store
> all datetimes with a UTC tzinfo object.  A nice, pickle-efficient UTC
> timezone is a prerequisite for the second choice.

Cool.  If I do it, I plan to go the tzinfo route.  I've gotten some 
other go-aheads privately, so unless someone voices a strong objection 
I'll proceed in the next couple of weeks.

To your point, as raised by Tim, of efficient pickles: the attached 
patch to pytz (Stuart, this is a bit different than the changes I sent 
you earlier) is better in this regard than the one Tim looked at.  I 
don't know if we could get it much smaller, since this __reduce__ 
doesn't include any arguments.  Stuart hasn't said whether or not he's 
willing to make these changes to pytz.  If not, I'll figure out what to 
do then. :-)

 >>> from pytz import utc, timezone
 >>> import cPickle as pickle
 >>> import datetime
 >>> n = datetime.datetime.now()
 >>> ntz = n.replace(tzinfo=utc)
 >>> p = pickle.dumps(n, 1)
 >>> ptz = pickle.dumps(ntz, 1)
 >>> len(p), len(ptz), len(ptz)-len(p)
(39, 57, 18)

Jim, by the way, doesn't care as much about the pickle size of the 
class names because of the newer pickle protocol Tim mentioned.  He 
wants small pickles but also wants to assure that there is only one 
instance of the UTC timezone in memory.  I think this patch fulfills 
this as well.

 >>> newtz = pickle.loads(ptz)
 >>> newtz == ntz
True
 >>> newtz is ntz
False
 >>> newtz.tzinfo is ntz.tzinfo
True

Additionally, I think that the pytz.timezone('UTC') call should return 
the same instance; the patch does that as well.

 >>> timezone('UTC') is utc
True

So everyone is clear, hear are some more examples, if Stuart accepts 
the patch or something similar to it.

Current call to get a now that will be stored:

dt = datetime.datetime.utcnow()

After change:

from pytz import utc
dt = datetime.datetime.now(utc)

The call to convert timezone-aware datetimes from a user to utc will be 
this:

from pytz import utc
aware.astimezone(utc)

Gary


-------------- next part --------------
A non-text attachment was scrubbed...
Name: untitled text 13
Type: application/octet-stream
Size: 1786 bytes
Desc: not available
Url : http://mail.zope.org/pipermail/zope3-dev/attachments/20050226/9892e857/untitledtext13.obj


More information about the Zope3-dev mailing list