[Python-Dev] PEP 431 Time zone support improvements (original) (raw)
Lennart Regebro regebro at gmail.com
Fri Dec 28 21:23:46 CET 2012
- Previous message: [Python-Dev] [Python-checkins] cpython (merge 2.7 -> 2.7): Null merge.
- Next message: [Python-Dev] PEP 431 Time zone support improvements - Update
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Happy Holidays! Here is the update of PEP 431 with the changes that emerged after the earlier discussion.
A raw download is here: https://raw.github.com/regebro/tz-pep/master/pep-04tz.txt
PEP: 431 Title: Time zone support improvements Version: RevisionRevisionRevision Last-Modified: DateDateDate Author: Lennart Regebro <regebro at gmail.com> BDFL-Delegate: Barry Warsaw Status: Draft Type: Standards Track Content-Type: text/x-rst Created: 11-Dec-2012 Post-History: 11-Dec-2012, 28-Dec-2012
Abstract
This PEP proposes the implementation of concrete time zone support in the Python standard library, and also improvements to the time zone API to deal with ambiguous time specifications during DST changes.
Proposal
Concrete time zone support
The time zone support in Python has no concrete implementation in the standard library outside of a tzinfo baseclass that supports fixed offsets. To properly support time zones you need to include a database over all time zones, both current and historical, including daylight saving changes. But such information changes frequently, so even if we include the last information in a Python release, that information would be outdated just a few months later.
Time zone support has therefore only been available through two third-party
modules, pytz
and dateutil
, both who include and wrap the "zoneinfo"
database. This database, also called "tz" or "The Olsen database", is the
de-facto standard time zone database over time zones, and it is included in
most Unix and Unix-like operating systems, including OS X.
This gives us the opportunity to include the code that supports the zoneinfo data in the standard library, but by default use the operating system's copy of the data, which typically will be kept updated by the updating mechanism of the operating system or distribution.
For those who have an operating system that does not include the zoneinfo
database, for example Windows, the Python source distribution will include a
copy of the zoneinfo database, and a distribution containing the latest
zoneinfo database will also be available at the Python Package Index, so it
can be easily installed with the Python packaging tools such as
easy_install
or pip
. This could also be done on Unices that are no
longer recieving updates and therefore has an outdated database.
With such a mechanism Python would have full time zone support in the standard library on any platform, and a simple package installation would provide an updated time zone database on those platforms where the zoneinfo database isn't included, such as Windows, or on platforms where OS updates are no longer provided.
The time zone support will be implemented by making the datetime
module
into a package, and creating a new submodule called `timezone, based on Stuart Bishop's
pytz`` module.
Getting the local time zone
On Unix there is no standard way of finding the name of the time zone that is
being used. All the information that is available is the time zone
abbreviations, such as EST
and PDT
, but many of those abbreviations
are ambigious and therefore you can't rely on them to figure out which time
zone you are located in.
There is however a standard for finding the compiled time zone information
since it's located in /etc/localtime
. Therefore it is possible to create
a local time zone object with the correct time zone information even though
you don't know the name of the time zone. A function in datetime
should
be provided to return the local time zone.
The support for this will be made by integrating Lennart Regebro's
tzlocal
module into the new timezone
module.
For Windows it will look up the local Windows time zone name, and use a mapping between Windows time zone names and zoneinfo time zone names provided by the Unicode consortium to convert that to a zoneinfo timezone.
The mapping should be updated before each major or bugfix release, scripts
for doing so will be provided in the Tools/
directory.
Ambiguous times
When changing over from daylight savings time the clock is turned back one hour. This means that the times during that hour happens twice, once without DST and then once with DST. Similarily, when changing to daylight savings time, one hour goes missing.
The current time zone API can not differentiating between the two ambiguous times during a change from DST. For example, in Stockholm the time of 2012-11-28 02:00:00 happens twice, both at UTC 2012-11-28 00:00:00 and also at 2012-11-28 01:00:00.
The current time zone API can not disambiguate this and therefore it's unclear which time should be returned::
# This could be either 00:00 or 01:00 UTC:
>>> dt = datetime(2012, 10, 28, 2, 0, tzinfo=timezone('Europe/Stockholm'))
# But we can not specify which:
>>> dt.astimezone(timezone('UTC'))
datetime.datetime(2012, 10, 28, 1, 0, tzinfo=<UTC>)
pytz
solved this problem by adding is_dst
parameters to several
methods of the tzinfo objects to make it possible to disambiguate times when
this is desired.
This PEP proposes to add these is_dst
parameters to the relevant methods
of the datetime
API, and therefore add this functionality directly to
datetime
. This is likely the hardest part of this PEP as this involves
updating the C version of the datetime
library with this functionality,
as this involved writing new code, and not just reorganizing existing
external libraries.
Implementation API
The zoneinfo database
The latest version of the zoneinfo database should exist in the
Lib/tzdata
directory of the Python source control system. This copy of
the database should be updated before every Python feature and bug-fix
release, but not for releases of Python versions that are in
security-fix-only-mode.
Scripts to update the database will be provided in Tools/
, and the
release instructions will be updated to include this update.
The new datetime.timezone
-module
The public API of the new timezone
-module contains one new class, one new
function and one new exception.
New class:
DstTzInfo
This class provides a concrete implementation of the
zoneinfo
base class that implements DST support.New function :
timezone(name=None, db_path=None)
This function takes a name string that must be a string specifying a valid zoneinfo timezone, ie "US/Eastern", "Europe/Warsaw" or "Etc/GMT+11". If not given, the local timezone will be looked up. If an invalid zone name are given, or the local timezone can not be retrieved, the function raises
UnknownTimeZoneError
.The function also takes an optional path to the location of the zoneinfo database which should be used. If not specified, the function will look for databases in the following order:
Use the database in
/usr/share/zoneinfo
, if it exists.Check if the
tzdata-update
module is installed, and then use that database.Check the Python-provided database in
Lib/tzdata
.
If no database is found an
UnknownTimeZoneError
or subclass thereof will be raised with a message explaining that no zoneinfo database can be found, but that you can install one with thetzdata-update
package.New Exception:
UnknownTimeZoneError
This exception is a subclass of KeyError and raised when giving a time zone specification that can't be found::
datetime.Timezone('Europe/New_York') Traceback (most recent call last): ... UnknownTimeZoneError: There is no time zone called 'Europe/New_York'
Changes in the datetime
-module
A new is_dst
parameter is added to several of the tzinfo
methods to
handle time ambiguity during DST changeovers.
tzinfo.utcoffset(self, dt, is_dst=False)
tzinfo.dst(self, dt, is_dst=False)
tzinfo.tzname(self, dt, is_dst=False)
The is_dst
parameter can be False
(default), True
, or None
.
False
will specify that the given datetime should be interpreted as not
happening during daylight savings time, ie that the time specified is after
the change from DST.
True
will specify that the given datetime should be interpreted as happening
during daylight savings time, ie that the time specified is before the change
from DST.
None
will raise an AmbiguousTimeError
exception if the time specified
was during a DST change over. It will also raise a NonExistentTimeError
if a time is specified during the "missing time" in a change to DST.
There are also three new exceptions:
InvalidTimeError
This exception serves as a base for
AmbiguousTimeError
andNonExistentTimeError
, to enable you to trap these two separately. It will subclass from ValueError, so that you can catch these errors together with inputs like the 29th of February 2011.AmbiguousTimeError
This exception is raised when giving a datetime specification that
are ambigious
while setting is_dst
to None::
>>> datetime(2012, 11, 28, 2, 0,
tzinfo=timezone('Europe/Stockholm'), is_dst=None) >>> Traceback (most recent call last): ... AmbiguousTimeError: 2012-10-28 02:00:00 is ambiguous in time zone Europe/Stockholm
NonExistentTimeError
This exception is raised when giving a datetime specification that
are ambigious
while setting is_dst
to None::
>>> datetime(2012, 3, 25, 2, 0,
tzinfo=timezone('Europe/Stockholm'), is_dst=None) >>> Traceback (most recent call last): ... NonExistentTimeError: 2012-03-25 02:00:00 does not exist in time zone Europe/Stockholm
The tzdata-update
-package
The zoneinfo database will be packaged for easy installation with
easy_install
/pip
/buildout
. This package will not install any
Python code, and will not contain any Python code except that which is needed
for installation.
Differences from the pytz
API
pytz
has the functionslocalize()
andnormalize()
to work around thattzinfo
doesn't have is_dst. Whenis_dst
is implemented directly indatetime.tzinfo
they are no longer needed.timezone()
will return the local time zone if called without parameters.The class
pytz.StaticTzInfo
is there to provide theis_dst
support for static timezones. Whenis_dst
support is included indatetime.tzinfo
it is no longer needed.InvalidTimeError
subclasses fromValueError
.
Discussion
Should the windows installer include the data package?
It has been suggested that the Windows installer should include the data package. This would mean that an explicit installation no longer would be needed on Windows. On the other hand, that would mean that many using Windows would not be aware that the database quickly becomes outdated and would not keep it updated.
Resources
Copyright
This document has been placed in the public domain. -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.python.org/pipermail/python-dev/attachments/20121228/35d3eaf4/attachment-0001.html>
- Previous message: [Python-Dev] [Python-checkins] cpython (merge 2.7 -> 2.7): Null merge.
- Next message: [Python-Dev] PEP 431 Time zone support improvements - Update
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]