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

Gary Poster gary at zope.com
Thu Feb 24 10:23:16 EST 2005


On Feb 24, 2005, at 9:45 AM, Garrett Smith wrote:

Hey Garrett.  Thanks for writing. :-)


> Gary Poster wrote:
>> Problems:
>> - working with mixed Python timezone-aware and -naive datetimes is a
>> big pain (i.e., they don't work together well, and are not intended to
>> AFAIK).
>
> :) Has anyone *not* Googled:
>
>   TypeError: can't compare offset-naive and offset-aware datetimes

:-)

>
>> - Given a choice, timezone-aware datetimes are more explicit, clear,
>> and effective.  The Zope 3 code base does not use timezone-aware
>> datetimes. [1]
>
> I've gone the other way -- I store everything without a time zone.
>
> I've found that maintaining time zone info is a pain:
>
> - A great source of annoying bugs
> - RDBs often don't support tz
>
> A datetime without a tz is either UTC or "dont care", which is known to
> the application. I've found this to work pretty well.

Except this is not explicit--with that approach, a datetime without a 
tz may be either, as you said.  You have to know what generated the 
datetime in order to know the meaning.  I think we've experience pain 
with this sort of guessing/implicit knowledge pattern in the past.  
With the approach I suggest the distinction is clear and explicit.

RDB storage already requires conversion to and from.  I don't think 
this is a compelling argument.  The explicitness of a timezone makes it 
easier to write a generic cast from a datetime to an RDB field: if a 
timezone is present and the RDB field stores UTC dates, the contract is 
clear.

We agree that this is a source of annoying bugs, but the presence or 
absence of timezones is not the source: the lack of uniformity is the 
problem.

>> - Displaying datetimes in UTC is not user friendly.  Users should see
>> datetimes in their timezones.
>
> Yep
>
>> Other observations:
>> - Working internally with utc datetimes is considered best
>>   practice[4]. The Zope 3 code base does store UTC dates, just
>> without a timezone.
>
> I prefer this.
>
>> Suggested Solution:
>> - zope.i18n should grow a picklable utc timezone that behaves well
>> with datetime.now()[5]
>> - datetimes generated in the Zope core to be stored should have a utc
>> timezone (i.e., datetime.now(zope.i18n.utc)--again, see footnote [5])
>
> I don't see the advantage here.

explicitness (see above :-)

> Where do we deal with time zone's, from an input standpoint, that 
> forces
> us to work with tz-aware values?

I'm not sure I understand the question.  Timezones are always important 
if you are writing a datetime-aware app (such as core Zope 3) that is 
intended to have one app instance that is usable simultaneously in 
multiple timezones.  Stephan's i18n package does a good job of it, with 
a desire to do more, and the datetimeutils certainly care.

> (I agree that display should *usually* take tz into account, but this 
> is
> up to the view.)

Sure.  None of what I've said disagrees with that.

>> - datetimes generated in the Zope core for display should always have
>> "localized" timezones.  Specifically:
>>    * zope.interface.common should grow an ITZInfo interface
>>    * zope.app.i18n should grow an adapter that adapts a default
>> request to an ITZInfo.  It will be intentionally dumb--always
>> returning i18n.utc--but will be intended to be a hook point for
>> applications to specify other defaults or heuristics for getting the
>> appropriate display timezone for a given request.  If anyone wants to
>> improve the default, great, but I'm not planning on it.
>
> Don't we grab tz info from the browser request in parseDatetimetz? I
> would imagine this would be the default adapter for browser requests.

To my knowledge (and I've asked around here), this is not available in 
the browser request (either the HTTP request headers or the Zope 3 
request object).  If you or anyone else knows differently, please let 
me know.  For some locales you can probably figure it out (a locale 
with only one timezone, theoretically), but for en_US, for instance, 
the locale just has a bunch of possible timezones, and guessing is 
difficult at best.  We don't want to guess.

>>    * zope.i18n should grow a convenience method to convert dates from
>> utc to another timezone [6]
>
> It's surprising that Python's datetime module doesn't do this.

See Tim's email. :-)  Yay!  (and whoops)

> But, if datetime values are stored sans-tz, we probably need this a lot
> less. (Not addressing locale-specific formatting here.)

If your datetimes are still understood to be utc, then you're going to 
have to do the same sort of thing, but actually with one more line of 
work AFAIK.

>>    * 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)
>
> I haven't looked at that code in a while, but I would hope that:
>
>   request.locale.dates.getFormatter(...)
>
> would provide a formatter that displayed localized time given a UTC
> value (no time zone). If it doesn't, it seems like a bug.

I don't think it's easily accomplished (for the problems I mentioned 
above in which getting a timezone from the request is not cut and dry), 
and no, it is not in the current code AFAIK.  Because getting a time 
zone is not cut and dry, it needs to be app behavior (involving things 
like system defaults, principal annotations for preferred timezones, 
etc. as desired for the app).

I wrote this proposal in part to see if anyone knew I was wrong about 
being able to reliably get tz info from the browser.  I don't think I 
am.

> So, if we don't lug around tz, the 'switch' requirement goes away:
>
>   formatter = request.locale.dates.getFormatter(...)
>   return formatter.format(date)
>
> (If the value has a tz, the formatter should not convert the value to
> the locale time zone.)
>
>> 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.
>
> The change seems like some unneeded complexity, but I'm not not making 
> a
> formal objection :)

:-)  OK.  On the basis of this, I'm still inclined to move forward.

> Let me just summarize:

OK, I will too.

> - Storing time zones is pain -- avoid it unless the application calls
> for it. The fact that all Zope dates will have the same offset (0) 
> tells
> me this isn't needed.

This is a case when explicitness is a win.  The problem is not 
timezones but heterogeneity of naive and aware datetimes.

> - Only worry about 'switching' during formatting. And it's not so much
> 'switching' as 'display this in my time zone'.

If it could be that easy, that would be great.  I need someone to tell 
me where I'm wrong then.  I won't make anyone else complicit in my 
errors, but I have asked around here a bit.

Gary



More information about the Zope3-dev mailing list