[Python-Dev] Add aware local time support to datetime module
Lennart Regebro
regebro at gmail.com
Sun Aug 8 10:37:21 CEST 2010
On Wed, Aug 4, 2010 at 19:46, Alexander Belopolsky
<alexander.belopolsky at gmail.com> wrote:
> [I've got no response from python-ideas, so I am forwarding to python-dev.]
>
> With addition of fixed offset timezone class and the timezone.utc
> instance [0], it is easy to get UTC time as an aware datetime
> instance:
>
>>>> datetime.now(timezone.utc)
> datetime.datetime(2010, 8, 3, 14, 16, 10, 670308, tzinfo=datetime.timezone.utc)
>
> However, if you want to keep time in your local timezone, getting an
> aware datetime is almost a catch 22. If you know your timezone UTC
> offset, you can do
>
>>>> EDT = timezone(timedelta(hours=-4))
>>>> datetime.now(EDT)
> datetime.datetime(2010, 8, 3, 10, 20, 23, 769537,
> tzinfo=datetime.timezone(datetime.timedelta(-1, 72000)))
>
> but the problem is that there is no obvious or even correct way to
> find local timezone UTC offset. [1]
>
> In a comment on issue #5094 ("datetime lacks concrete tzinfo
> implementation for UTC"), I proposed to address this problem in a
> localtime([t]) function that would return current time (or time
> corresponding to the optional datetime argument) as an aware datetime
> object carrying local timezone information in a tzinfo set to an
> appropriate timezone instance. This solution is attractive by its
> simplicity, but there are several problems:
>
> 1. An aware datetime cannot carry all information that system
> localtime() supplies in a time tuple. Specifically, the is_dst flag
> is lost. This is not a problem for most applications as long as
> timezone UTC offset and timezone name are available, but may be an
> issue when interoperability with the time module is required.
>
> 2. Datetime's tzinfo interface was designed with the idea that
> <2010-11-06 12:00 EDT> + <1 day> = <2010-11-07 12:00 EST>, not
> <2010-11-07 12:00 EDT>. It other words, if I have lunch with someone
> at noon (12:00 EDT) on Saturday the day before first Sunday in
> November, and want to meet again "at the same time tomorrow", I mean
> 12:00 EST, not 24 hours later. With localtime() returning datetime
> with tzinfo set to fixed offset timezone, however, localtime() +
> timedelta(1) will mean exactly 24 hours later and the result will be
> expressed in an unusual for the given location timezone.
>
> An alternative approach is the one recommended in the python manual.
> [3] One could implement a LocalTimezone class with utcoffset(),
> tzname() and dst() extracting information from system mktime and
> localtime calls. This approach has its own shortcomings:
>
> 1. While adding integral number of days to datetimes in business
> setting, it is natural to expect automatic timezone adjustments, it is
> not as clearcut when adding hours or minutes.
>
> 2. The tzinfo.utcoffset() interface that expects *standard* local time
> as an argument is confusing to many users. Even the "official"
> example in the python manual gets it wrong. [4]
>
> 3. datetime(..., tzinfo=LocalTimezone()) is ambiguous during the
> "repeated hour" when local clock is set back in DST to standard time
> transition.
>
> As far as I can tell, the only way to resolve the last problem is to
> add is_dst flag to the datetime object, which would also be the
> only way to achieve full interoperability between datetime objects and
> time tuples. [5]
>
> The traditional answer to call for improvement of timezone support in
> datetime module has been: "this is upto 3rd parties to implement."
> Unfortunately, stdlib is asking 3rd parties to implement an impossible
> interface without giving access to the necessary data. The
> impossibility comes from the requirement that dst() method should find
> out whether local time represents DST or standard time while there is
> an hour each year when the same local time can be either. The missing
> data is the system UTC offset when it changes historically. The time
> module only gives access to the current UTC offset.
>
> My preference is to implement the first alternative - localtime([t])
> returning aware datetime with fixed offset timezone. This will solve
> the problem of python's lack of access to the universally available
> system facilities that are necessary to implement any kind of aware
> local time support.
For all of the reasons you give above, I think it's a bad idea. :-)
You need a proper time zone database to solve these issues, like pytz.
Which incidentally solves the ambiguity problem as well. so the
solution is pytz. :-)
What pytz doesn't have (but dateutil.tz does) is a timezone object
that uses the operating systems local timezone data, like
/etc/localzone on unix. That could be interesting to include,
possibly. Having a fixed time zone offset object for the localtime
seems a bad idea. The problem it solves is easy to get around, but the
problems created are not.
--
Lennart Regebro, Colliberty: http://www.colliberty.com/
Python, Zope, Plone blog: http://regebro.wordpress.com/
Telephone: +33 661 58 14 64
More information about the Python-Dev
mailing list