This issue tracker has been migrated to GitHub ,
and is currently read-only.
For more information,
see the GitHub FAQs in the Python's Developer Guide.
Created on 2012年05月09日 22:11 by Chris.Bergstresser, last changed 2022年04月11日 14:57 by admin. This issue is now closed.
| Files | ||||
|---|---|---|---|---|
| File name | Uploaded | Description | Edit | |
| 14766.patch | greg.weller, 2012年05月10日 11:55 | review | ||
| 14766.patch | greg.weller, 2012年05月10日 23:10 | review | ||
| Messages (10) | |||
|---|---|---|---|
| msg160314 - (view) | Author: Chris Bergstresser (Chris.Bergstresser) | Date: 2012年05月09日 22:11 | |
The datetime module says:
An object d of type time or datetime may be naive or aware. d is aware if d.tzinfo is not None and d.tzinfo.utcoffset(d) does not return None. If d.tzinfo is None, or if d.tzinfo is not None but d.tzinfo.utcoffset(d) returns None, d is naive.
However, I can create two non-naive timezones (under this definition) which throw an exception when they're compared, because one is being considered offset-naive:
>>> import pytz, datetime
>>> UTC_TZ = pytz.utc
>>> EASTERN_TZ = pytz.timezone('America/New_York')
>>> d1 = datetime.time(10, tzinfo = UTC_TZ)
>>> d1
datetime.time(10, 0, tzinfo=<UTC>)
>>> d1.tzinfo
<UTC>
>>> d1.utcoffset(d1)
datetime.timedelta(0)
>>> d2 = datetime.time(10, tzinfo = EASTERN_TZ)
>>> d2
datetime.time(10, 0, tzinfo=<DstTzInfo 'America/New_York' EST-1 day, 19:00:00 STD>)
>>> d2.tzinfo
<DstTzInfo 'America/New_York' EST-1 day, 19:00:00 STD>
>>> d2.tzinfo.utcoffset(d2)
datetime.timedelta(-1, 68400)
>>> d1 < d2
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: can't compare offset-naive and offset-aware times
|
|||
| msg160315 - (view) | Author: R. David Murray (r.david.murray) * (Python committer) | Date: 2012年05月09日 22:56 | |
An equivalent test using python 3.2's datetime.timezone works fine. Are you sure it isn't a bug in pytz? |
|||
| msg160316 - (view) | Author: Chris Bergstresser (Chris.Bergstresser) | Date: 2012年05月09日 23:44 | |
It doesn't seem to be a bug in pytz. AFAICT, the only methods that get called during the time comparison is "utcoffset" on the UTC timezone, and "utcoffset" on the New York timezone. Looking closer at it, it seems that Python is calling d1.tzinfo.utcoffset(None), rather than d1.tzinfo.utcoffset(d1). This is a problem, because the New York timezone cannot calculate the utcoffset without knowing what date it's calculating. As a result, it returns None rather than potentially guessing wrong. |
|||
| msg160317 - (view) | Author: R. David Murray (r.david.murray) * (Python committer) | Date: 2012年05月10日 00:07 | |
Ah. datetime.timezone wouldn't have that issue since it doesn't deal with DST. The 3.3 python version of datetime calls utcoffset in the same way as you describe, and it is supposed to have the same behavior as the C version, so probably 3.2/3.3 has the bug as well. (It does look like a bug to me.) Note that 2.6 is in security fix only mode, so this can only get corrected in 2.7 and 3.2/3.3. I'm surprised this hasn't been reported before. |
|||
| msg160335 - (view) | Author: Greg Weller (greg.weller) | Date: 2012年05月10日 11:55 | |
I think this is a documentation bug. The criteria for datetime and time objects being aware are slightly different. A datetime object d is aware if d.tzinfo.utcoffset(d) does not return None, while a time object t is aware if t.tzinfo.utcoffset(None) does not return None (time objects call utcoffset with None while datetime objects call utcoffset with self).
This accounts for the TypeError in the original example:
>>> import pytz, datetime
>>> UTC_TZ = pytz.utc
>>> EASTERN_TZ = pytz.timezone('America/New_York')
>>> d1 = datetime.time(10, tzinfo=UTC_TZ)
>>> d2 = datetime.time(10, tzinfo=EASTERN_TZ)
>>> repr(d1.tzinfo.utcoffset(None))
'datetime.timedelta(0)'
>>> repr(d2.tzinfo.utcoffset(None))
'None'
>>> d1 < d2
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: can't compare offset-naive and offset-aware times
It looks like this example is flawed according to http://pytz.sourceforge.net/ : "Unfortunately using the tzinfo argument of the standard datetime constructors ‘’does not work’’ with pytz for many timezones. It is safe for timezones without daylight savings trasitions though, such as UTC." (If you think about it, the error still makes sense: the UTC time is aware and the eastern time is naive -- any DST time object has to be naive -- but this has more to do with pytz).
It doesn't make sense to have time objects pass self to utcoffset because utcoffset expects a datetime object. You shouldn't be able to infer what the UTC offset is from a time object unless the offset is constant, in which case you don't even need the time object. If the UTC offset isn't constant, you need the date, which a time object doesn't have. I think this is the logic behind having datetime objects call utcoffset(self) and time objects call utcoffset(None).
I've attached a small patch for the documentation.
|
|||
| msg160342 - (view) | Author: R. David Murray (r.david.murray) * (Python committer) | Date: 2012年05月10日 12:53 | |
My, that's embarrassing. I somehow entirely missed the fact that we were dealing with times and not dates here. What you say makes sense to me, and the doc patch looks good. |
|||
| msg160351 - (view) | Author: Chris Bergstresser (Chris.Bergstresser) | Date: 2012年05月10日 15:14 | |
That patch fixes the documentation there, but the description at the top of the distinction between naive and aware time objects at the top datetime module is still wrong. Here it is: ----------------- There are two kinds of date and time objects: "naive" and "aware". This distinction refers to whether the object has any notion of time zone, daylight saving time, or other kind of algorithmic or political time adjustment. Whether a naive datetime object represents Coordinated Universal Time (UTC), local time, or time in some other timezone is purely up to the program, just like it’s up to the program whether a particular number represents metres, miles, or mass. Naive datetime objects are easy to understand and to work with, at the cost of ignoring some aspects of reality. ------------------ The distinction is not whether the object has any notion of "time zone, daylight saving time, or other kind of algorithmic or political time adjustment", but instead whether, in the context it's being used, it can calculate an offset to UTC. A naive time can be used to create an aware datetime. |
|||
| msg160380 - (view) | Author: Greg Weller (greg.weller) | Date: 2012年05月10日 23:10 | |
I agree that the language in the quoted paragraph makes it sound as if any object with a non-None tzinfo is aware, which isn't the case. I've changed the first couple sentences to, I think, better reflect what characterizes an object as being aware. |
|||
| msg160676 - (view) | Author: Roundup Robot (python-dev) (Python triager) | Date: 2012年05月15日 02:33 | |
New changeset 28ed782949f9 by R David Murray in branch '3.2': #14766: Add correct algorithm for when a 'time' object is naive. http://hg.python.org/cpython/rev/28ed782949f9 New changeset b1e03e863386 by R David Murray in branch '3.2': #14766: Reflow the altered paragraphs. http://hg.python.org/cpython/rev/b1e03e863386 New changeset 6ff172db8114 by R David Murray in branch 'default': Merge #14766: Add correct algorithm for when a 'time' object is naive. http://hg.python.org/cpython/rev/6ff172db8114 New changeset 5d1b32e33e67 by R David Murray in branch '2.7': #14766: Add correct algorithm for when a 'time' object is naive. http://hg.python.org/cpython/rev/5d1b32e33e67 New changeset a002638919d8 by R David Murray in branch '2.7': #14766: Reflow the altered paragraphs. http://hg.python.org/cpython/rev/a002638919d8 |
|||
| msg160678 - (view) | Author: R. David Murray (r.david.murray) * (Python committer) | Date: 2012年05月15日 02:38 | |
I reformatted the first hunk a bit, hopefully to make it even a little bit clearer. We're still punting the actual definition to the later section, but I think that's appropriate. Thanks for the patch, Greg. |
|||
| History | |||
|---|---|---|---|
| Date | User | Action | Args |
| 2022年04月11日 14:57:30 | admin | set | github: 58971 |
| 2012年05月15日 02:38:05 | r.david.murray | set | status: open -> closed resolution: fixed messages: + msg160678 stage: needs patch -> resolved |
| 2012年05月15日 02:33:48 | python-dev | set | nosy:
+ python-dev messages: + msg160676 |
| 2012年05月10日 23:10:38 | greg.weller | set | files:
+ 14766.patch messages: + msg160380 |
| 2012年05月10日 15:14:47 | Chris.Bergstresser | set | messages: + msg160351 |
| 2012年05月10日 12:53:50 | r.david.murray | set | messages: + msg160342 |
| 2012年05月10日 11:55:28 | greg.weller | set | files:
+ 14766.patch nosy: + greg.weller messages: + msg160335 keywords: + patch |
| 2012年05月10日 00:07:56 | r.david.murray | set | keywords:
+ easy stage: needs patch messages: + msg160317 versions: + Python 2.7, Python 3.2, Python 3.3, - Python 2.6 |
| 2012年05月09日 23:44:33 | Chris.Bergstresser | set | messages: + msg160316 |
| 2012年05月09日 22:56:33 | r.david.murray | set | nosy:
+ r.david.murray, belopolsky messages: + msg160315 |
| 2012年05月09日 22:11:09 | Chris.Bergstresser | create | |