Add aware local time support to datetime module

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
but the problem is that there is no obvious or even correct way to find local timezone UTC offset. [1] I 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 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. [0] http://docs.python.org/dev/library/datetime.html#timezone-objects [1] http://bugs.python.org/issue1647654 [2] http://bugs.python.org/issue5094#msg106997 [3] http://docs.python.org/library/datetime.html#tzinfo-objects [4] http://bugs.python.org/issue9063 [5] http://bugs.python.org/issue9004
participants (1)
-
Alexander Belopolsky