Friday, March 16, 2018¶
Time zones¶
Yesterday I opened #2345 and started working on it. Here comes the result.
Until today we had just had a field User.timezone
(a
Charfield(max_length=15)
when USE_TZ
was True. In
order to get an aware datetime of the start and end times of a
session, we used the user’s time zone. Which was okay unless the user
travels and works in changing time zones.
Jane is the only production site with USE_TZ
Now I added a timezone field per working.Session
as well.
But before doing this I reviewed and optimized the whole system a bit. I added a choicelist about.Timezones which defines a subset of all timezones known to pytz. This has one theoretical disadvantage (it requires local system admins to define their own list of timezones allowed on their site) but some advantages: it reduces server load because it uses only 2 instead of 15 bytes per Session record and (more important) avoids a lookup into the pytz database (a dict containing 439 keys) for every incoming web request. Also it will probably be more ergonimic.
>>> import pytz
>>> len(pytz.common_timezones)
439
The django.utils.timezone.activate()
function (called for every
incoming request) is smart enough and would avoid the lookup if we
would provide the tzinfo
object ourselves:
def activate(timezone):
if isinstance(timezone, tzinfo):
_active.value = timezone
elif isinstance(timezone, six.string_types):
_active.value = pytz.timezone(timezone)
else:
raise ValueError("Invalid timezone: %r" % timezone)
We currently store the timezone (either per user or system-wide) as a string. That is, for the moment we are using the inefficient variant.
Where to put our TimeZones choicelists? To lino.modlib.about
?
Or into a separate plugin lino.modlib.timezones
? I noted that
we have two plugins lino.modlib.about
and
lino.modlib.system
which should maybe get merged. One
difference is that about
is always there while system
only when needed. Though it is needed by lino.modlib.users
and
therefore they are almost always both present.
Changes:
New choicelist
lino.modlib.about.TimeZones
with at least onedefault
.Replaced the CharField timezone by a ChoiceListField time_zone (the correct English spelling is with two words).
In
lino.core.auth.middleware
we now use the tzinfo objects on every choice ofTimeZones
.
Another change of more general impact:
When
lino.core.choicelists.ChoiceListField.to_python()
receives a string, then this should be thevalue
of a choice. Now it supports also specifying aname
.
New page about : Information about a site.
Here is the line to modify in the restore.py
file
when upgrading a production site:
kw.update(time_zone=settings.SITE.models.about.TimeZones.find(text=timezone))
After installing it on Jane I started to get the feeling that maintaining a local list of “allowed” time zones will be cumbersome. To be observed.
About inspired working¶
I have been asking myself “Why the hell did I open and fix that #2345? Why now? Aren’t there more urgent things to do?”
It is what I would call inspired working. Every well-educated project manager will give me -1 for this technique.
It happened after updating our jobs page and reviewing the Developer Guide (in case somebody looks at it).